Reputation: 1612
I'm using NGRX and RxJS in Angular2 application. When use try to save record update, I generate an action 'UPDATE', and I want to call API to update Database.
The issue is that everything after ".filter ( action => action.type==UPDATE )" is invoke 4 times.
I don't understand why. I try manything and code change but issue still here...
My code :
private actions$ : BehaviorSubject<Action> = new BehaviorSubject<Action>({type: null, payload: null});
.../....
// catch employee selection
let update = this.actions$
.filter ( action => action.type==UPDATE )
// **** following are executed 4 times ****
.do( () => this._store.dispatch({type: REDUCER_UPDATING }) )
.mergeMap ( action =>this._APIService.updateEmployee(action.payload) ); //
// merge all stream and dispatch action
let all = Observable.merge (update, load, selectItem);
all.subscribe ((action:Action) => this._store.dispatch (action));
To see issue live :
https://plnkr.co/edit/zq4AsKJYILfrgItDNbHo?p=preview
Select an employee in Master Panel. In details panel, click save button. You will see in console that API is called 4 times :
REDUCER - {"type":"SELECTING_ITEM","payload":1}
REDUCER - {"type":"UPDATING"}
API - UPDATE_EMPLOYEE <====1
REDUCER - {"type":"UPDATING"}
API - UPDATE_EMPLOYEE <====2
REDUCER - {"type":"UPDATING"}
API - UPDATE_EMPLOYEE <====3
REDUCER - {"type":"UPDATING"}
API - UPDATE_EMPLOYEE <====4
REDUCER - {"type":"UPDATED"}
Thank you for your help !!
Upvotes: 0
Views: 1684
Reputation: 18665
I replaced the update
part with :
// catch employee selection
let update = this.actions$
.filter ( action => action.type==UPDATE )
// **** following are executed 4 times ****
.do( () => this._store.dispatch({type: REDUCER_UPDATING }) )
.mergeMap ( action =>this._APIService.updateEmployee(action.payload) )
.share(); //
This results in only one update appearing in the log.
The reason you observe the duplication of the updates is because every time you subscribe to the update stream, the observable chain is 'restarted'. This is what is called in RxJS a cold observable. The solution is simple, just add share
at the end of the observable that you want to share between several subscribers.
For more details on hot vs. cold, see the official documentation. You can also review the illustrated data and subscription flows.
Upvotes: 2