I have an Issue object, one property of which is an array of Tool objects. Issues and Tools are two different tables in my database.
In my issues-log.component I am dispatching an action to search for issues that match my search query. This works just fine.
The next thing I've been trying to do, is to take the list of issues and for each issue id, pass that to my tools service so that I can get the tools related to that issue.
The way I was able to get that working is to add another effect that listens for the ISSUE.SEARCH.COMPLETE action. Then I looped through the array of issues in my tools service so that I could call the API service for each issue id and add the tools property to that issue. This seems wrong in a couple ways. One is that for large lists of issues, it takes a long time to for all the tools to load and if I try to kick off another issues search I have to wait for the tools to load from the previous one before my app responds. Two, is that it seems wrong to pass the whole issues array into the tools service when I only need one issue id at a time for my tools API to get the list of tools associated with that issue; this doesn't make my tools service easily re-usable in other places in my app.
I would prefer not to wait until my API call to get the list of issues is done before I can start getting the tools associated with each issue id. Is it possible to add code in my issuesSearch$ effect, where commented below, to start adding the tools as my list of issues is being built?
Component:
@Component({
selector: issue-log,
template: `
<issue-search (search)="search($event)></issue-search>
<issue-list [issues]=$issues | async></issue-list>
`,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class IssueLogComponent {
issues$: Observable<Issue[]>;
constructor(private store: Store<fromRoot.State>) {
this.issues$ = store.select(fromRoot.getIssueSearchResults);
}
search(query) {
this.store.dispatch(new issue.IssueSearch(query));
}
}
Effect:
@Effect() issueSearch$: Observable<Action> = this.actions$
.ofType(issue.ISSUE_SEARCH)
.debounceTime(300)
.map(toPayload)
.switchMap(query => {
if (query === '') {
return empty();
}
const nextSearch$ = this.actions$.ofType(issue.ISSUE_SEARCH).skip(1);
return this.issueService.getIssuesFromQuery(query) //calls API service
.takeUntil(nextSearch$)
.mergeMap((res: Issue[]) => {
// How do I make another API call here, passing data from each element of res array?
return Observable.from([
new issue.IssueSearchComplete(res)
])
})
.catch(() => of(new issue.IssueSearchComplete([])));
});
I also tried calling my tools service from inside my issues service, but don't think this is the right approach either.