I have an ngrx effect function that initially looks like
importItems$ = createEffect(() => this.actions$.pipe(
ofType(ItemActions.loadItems),
mergeMap(() => this.itemService.getItems().pipe(
map((_) => {
let validItems:any
let invalidItems:any
var helper = new Helper()
// async operations
validItems = helper.loadValidItems().then((res) => validitem = res)
invalidItems = helper.loadInalidItems().then((res) => invaliditem = res)
// save to reducer
return ItemActions.loadItemsSuccess({validItems,invalidItems})
})
))
));
}
the problem is that
helper
operations are async, it needs to search a xlsx file which takes time.
The problem is that if i run this code, i get:
return ItemActions.loadItemsSuccess({validItems,invalidItems})
with
null
values, because
validItems = helper.loadValidItems().then((res) => validitem = res)
invalidItems = helper.loadInalidItems().then((res) => invaliditem = res)
take some time and are finished after return functions. So i used Promise all
Promise.all([
validItems = helper.loadValidItems().then((res) => validitem = res)
invalidItems = helper.loadInalidItems().then((res) => invaliditem = res)
]).then(() => {
return ItemActions.loadItemsSuccess({validItems,invalidItems})
})
but now it doesnt work. How to solve this problem?
I figured out, that there cant be return function inside promise all method, but i need somehow to wait for two async operations to end, then take their data, and then set them in reducer.
promises aren't handled in a correct way.
fixed version:
importItems$ = createEffect(() => this.actions$.pipe(
ofType(ItemActions.loadItems),
mergeMap(() => this.itemService.getItems()) // result is unused. idk why it is in the code
mergeMap((items) => forkJoin({ // forkJoin will make sure event is emitted to the next operator when everything is complete
validItems: helper.loadValidItems(),
invalidItems: helper.loadInalidItems()
})),
map((data) => ItemActions.loadItemsSuccess(data))
));