Reputation: 1120
In my angular6 app, i have three cateories, catA, catB, catC. Each category needs data from 3 APIs. On clicking any category it loads the CategoryDetailsComponent, i dispatch action (LoadCategoryDetails).
I have implemented forjoin
to perform parallel api calls(in service) and also resolver
to ensure all the calls are done, only then the component should loaded.
categoryNames
array is emptyCategoryNames
array shows list of previous category (catA)Maybe one of the api call is taking time. and my resolver is not configured properly.
How to configure effects and resolver??
How to use forkjoin to make multiple calls and send data to component?
dipatch action and subscribe to selector
ngOnInit() {
const id = parseInt(this.route.snapshot.paramMap.get('categoryId'), 10);
this.store.dispatch(new fromCategory.LoadCategoryDetails(id));
this.store.select(getCategoryDetails)
.subscribe((data) => {
this.categoryDetails = data[0];
this.journeys = data[1];
this.categories = data[2];
});
// filter only category name
// problem
this.categories.forEach( category => {
this.categoryNames.push(category.name);
});
}
effects (look for action and call service)
@Effect()
loadCategoryDetails$ = this.actions$.pipe(
ofType<fromCategory.LoadCategoryDetails>(CategoryActionTypes.LoadCategoryDetails),
switchMap((action) => {
return this.categoryService.getCategoryDetails(action.payload).pipe(
map(data => new fromCategory.LoadCategoryDetailsSuccess(data))
);
})
);
service func making multiple calls and using forkjoin
import { forkJoin } from 'rxjs';
getCategoryDetails(categoryId) {
const categoryDetails = this.http.get(url);
const journeys = this.http.get(url);
const courses = this.http.get(url);
return forkJoin([categoryDetails, journeys, courses]);
}
resolver
export class CategoryDetailsResolver implements Resolve<any> {
constructor(
private categoryService: CategoryService,
private router: Router) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
const categoryId = route.paramMap.get('categoryId');
return this.categoryService.getCategoryDetails(categoryId);
}
}
Thanks in advance.
Upvotes: 0
Views: 1135
Reputation: 7111
refactor your code to NOT use route.snapshot and see if that fixes it.
ngOnInit() {
this.route.data.subscribe((data) => {
if(data) {
this.store.dispatch(new fromCategory.LoadCategoryDetails(data.id));
this.store.select(getCategoryDetails)
.subscribe((data) => {
this.categoryDetails = data[0];
this.journeys = data[1];
this.categories = data[2];
this.categories.forEach( category => {
this.categoryNames.push(category.name);
});
});
}
});
}
Upvotes: 2
Reputation: 7931
Your implementation of forkjoin looks fine to me. But one problem I can see in your code is , you are iterating the categories outside of the getCategoryDetails callback. Since it is asynchronous , you should always ensure you are getting the categories before you do the iteration. For that you should move the code for iterating the categories to the successful callback function.
ngOnInit() {
const id = parseInt(this.route.snapshot.paramMap.get('categoryId'), 10);
this.store.dispatch(new fromCategory.LoadCategoryDetails(id));
this.store.select(getCategoryDetails)
.subscribe((data) => {
this.categoryDetails = data[0];
this.journeys = data[1];
this.categories = data[2];
this.categories.forEach( category => {
this.categoryNames.push(category.name);
});
});
// filter only category name
// problem
}
Upvotes: 0