I'm trying to do simple thing - after some entity saved (using http request) I want to navigate back to list route. The problem is : how to subscribe to success action (or may be reducer or effect?)
here is my actions code:
static SAVE_POST = '[POST] Save POST';
savePOST(Post): Action {
return {
type: PostActions.SAVE_POST,
payload: Post
};
}
static SAVE_POST_SUCCESS = '[POST] Save POST Success';
savePOSTSuccess(Post): Action {
console.log('action: savePostSuccess')
return {
type: PostActions.SAVE_POST_SUCCESS,
payload:Post
};
}
i'm using Effects:
@Effect() savePost$ = this.update$
.ofType(PostActions.SAVE_POST)
.map(action => action.payload)
.switchMap(post => this.svc.savePost(post))
.map(post => this.postActions.savePOSTSuccess(post));
reducer:
const initialState: PostListState = [];
export default function (state = initialState, action: Action): PostListState {
switch (action.type) {
case PostActions.LOAD_POST_SUCCESS: {
return action.payload;
}
case PostActions.SAVE_POST_SUCCESS: {
console.log('SavePOST SUCCESS',action.payload)
let index = _.findIndex(state, {_id: action.payload._id});
if (index >= 0) {
return [
...state.slice(0, index),
action.payload,
...state.slice(index + 1)
];
}
return state;
}
default: {
return state;
}
}
}
in my component i want to subscribe to success callback:
handlePostUpdated($event) {
this.post = this.code;
let _post: Post = Object.assign({}, { _id: this.id, name: this.name, text: this.post });
this.store.dispatch(this.postActions.savePOST(_post)); //not have "subscribe" method
}
Thanks for Help
You can subscribe to actions in components as well:
[...]
import { Actions } from '@ngrx/effects';
[...]
@Component(...)
class SomeComponent implements OnDestroy {
destroyed$ = new Subject<boolean>();
constructor(updates$: Actions) {
updates$.pipe(
ofType(PostActions.SAVE_POST_SUCCESS),
takeUntil(this.destroyed$)
)
.subscribe(() => {
/* hooray, success, show notification alert etc.. */
});
}
ngOnDestroy() {
this.destroyed$.next(true);
this.destroyed$.complete();
}
}
Based on this:https://netbasal.com/listening-for-actions-in-ngrx-store-a699206d2210 with some small modifications, as since ngrx 4 there is no Dispatcher anymore, but instead ActionsSubject:
import { ActionsSubject } from '@ngrx/store';
import { ofType } from "@ngrx/effects";
subsc = new Subscription();
constructor(private actionsSubj: ActionsSubject, ....) {
this.subsc = this.actionsSubj.pipe(
ofType('SAVE_POST_SUCCESS')
).subscribe(data => {
// do something...
});
}
ngOnDestroy() {
this.subsc.unsubscribe();
}
Sure. That's possible. Please consider this example of listening for a saved contact.
export class PageContactComponent implements OnInit, OnDestroy {
destroy$ = new Subject<boolean>();
constructor(private actionsListener$: ActionsSubject) {}
ngOnInit() {
this.actionsListener$
.pipe(ofType(ContactActionTypes.SAVE_SUCCESS))
.pipe(takeUntil(this.destroy$))
.subscribe((data: any) => {
// Do your stuff here
});
}
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
}
Here, I have created an ActionsSubject named actionsListener$. In this example I am listening to ContactActionTypes.SAVE_SUCCESS (an action that happens when a contact has been saved). Describe your code in the subscribe section and don't forget to destroy the subscription.
Edit: And here is what the Action looks like:
export enum ContactActionTypes {
SAVE_SUCCESS = "[Contact] Save Success",
}
export class ActionContactSaveSuccess implements Action {
readonly type = ContactActionTypes.SAVE_SUCCESS;
constructor(readonly payload: { contact: any }) {}
}
export type ContactActions = ActionContactSaveSuccess;