I have a modal window clicked that when the Add user
button is clicked it adds the value in the textbox
, after it does some internal calls like checking the validity of the value in the textbox
. The http
calls are executed in an effect, which gets called only for the first entry.
The problem is that the effect that does the back-end call is executed only once.
The template of the modal:
<button class="close" mat-button (click)="closeDialog()">x</button>
<h1 mat-dialog-title>Share with other users</h1>
<div mat-dialog-content>
<ng-container *ngFor="let principal of data.productList.sharedWith; trackBy: sharedPrincipalsTrackFunction">
<p>{{principal.uid}} <button (click)="removeUserFromSharedProductList(data.productList.name, principal.uid)">x</button></p>
</ng-container>
<mat-form-field>
<mat-label>Share with other users</mat-label>
<input matInput [(ngModel)]="data.userId">
</mat-form-field>
</div>
<div mat-dialog-actions>
<button class="btn btn-primary" mat-button (click)="addUserToProductList(data.productList.name, data.userId)" [disabled]="!data.userId">Add user</button>
</div>
Typescript code of the component:
addUserToProductList(productListName: string, userId: string) {
this.productListService.shareProductList(productListName, userId);
this.updateDialogData(userId);
}
productListService.shareProductList
:
shareProductList(productListName: string, userId: string) {
this._store.dispatch(
ProductListActions.shareProductListWithUser({
productListName: productListName,
userId: userId
})
);
}
effect:
shareProductListWithUser$ = createEffect(() =>
this._actions$.pipe(
ofType(ProductListActions.shareProductListWithUser),
mergeMap(action =>
forkJoin(
of(action.productListName),
this._productListOccService.shareProductListWithUser(
action.productListName,
action.userId
)
)
),
switchMap(([productListName, response]) => [
ProductListActions.getMyProductLists(),
ProductListActions.shareProductListWithUserSuccess({
productListName: productListName,
principalList: response
})
]),
catchError((error) => {
console.log('Acelasi handler de kkt');
return EMPTY;
}))})
)
);
the module file:
@NgModule({
declarations: [],
imports: [
CommonModule,
StoreModule.forFeature("productListState", productListReducer),
EffectsModule.forFeature([ProductListEffects])
],
providers: [ProductListOccService],
entryComponents: []
})
export class PrtListStoreModule {}
I debugged this, but I couldn't understand why the effect is called only once.
The problem is in catchError
, you need to add repeat
after it to enable the effect again.
catchError((error) => { // <- closes the stream
console.log('Acelasi handler de kkt');
return EMPTY;
}))}),
repeat(), // <- resubscribes
Ideally would be right to put catchError
in the .pipe
of the .shareProductListWithUser
, then you could avoid repeat
, but because you have dependencies on the response you can keep the code as it as and to achieve the desired behavior with repeat
.