Within an Angular component I have to retrieve data from an API then use it with some state data from an NGXS state variable. In my component I have this:
@Select(MyObjectState.get)
public readonly myobjects$: Observable<MyObject[]>;
What I want to do is this:
forkjoin([this.apiService.GetSomeData(), this.myobjects$])
.pipe(
map(([mydata, myobjects]) => {
...do some stuff
})
)
.subscribe((result) => {
...more stuff
})
The issue is that the 'forkjoin' never completes and calls the map operator. I'm not sure if the myobjects$
Observable just doesn't complete or what but it just hangs. I tested this by replacing myobjects$
with of([])
and then the 'forkjoin' completes.
How can I combine my state data with my api data?
forkJoin
will only emit when all of its sources complete. Depending on when you want your subscribe logic to execute, you have a few options.
forkjoin([
this.apiService.GetSomeData(),
this.myobjects$.pipe(take(1)), // <--- take(1)
]).pipe(
/* ... */
).subscribe(
result => { /* ... */ }
);
You can use the take
operator to cause your observable to complete after one emission, allowing forkJoin
to emit the results.
combineLatest([this.apiService.GetSomeData(), this.myobjects$]).pipe(
/* ... */
).subscribe(
result => { /* ... */ }
);
If you want to run your subscribe logic every time any source emits, you can use combineLatest
. This doesn't require the sources to complete, it only requires that each source emit at least one value.
myObjects$
emitsthis.apiService.GetSomeData().pipe(
switchMap(mydata => this.myobjects$.pipe(
map(myobjects => /* ... */
))
).subscribe(
result => { /* ... */ }
);
You can also use switchMap
. The above code takes emissions from your api service call, then maps them to a new observable. The emissions from this "inner observable" will be emitted.
You can use a nested .pipe()
so that your inner logic has access to both the mydata
emission as well as the myobjects
emissions.