Reputation: 1769
this._authService.loggedInUser$.pipe(switchMap((loggedInUser: LoggedInUser) => {
return this._userSerialService.getUserSerial().pipe(switchMap(serial => {
return this._usersService.getCurrentUser().pipe(switchMap(currentUser => [loggedInUser, currentUser, serial]));
}),
);
})).subscribe(([loggedInUser, currentUser, serial]) => {
});
The above code attempts to chain 3 observables together and map their results to an array using switchMaps. I need the result values for all three observables in my final subscription. However when I attempt to subscribe in the way shown above I'm given a compiler error that says `Type 'LoggedInUser' must have a 'Symbol.iterator' method that returns an iterator.
If I do subscribe(res => {}
, then res ends up being only the value of loggedInUser, not all three values.
What do I need to change in my code to make sure that I have access to all three values in my subscribe?
Upvotes: 1
Views: 396
Reputation: 14740
It does not look like switchMap is what you need. switchMap is used to "switch" a source observable under the hood so that a new observable can emit into the stream. It handles unsubscribing from the prior source and subscribing to the new one.
In your case, you can simply use combineLatest
. This will emit an array of all 3 values once all of the source observables have emitted a value and it will continue to emit whenever any of them receive a new value.
authUser$ = this._authService.loggedInUser$;
serial$ = this._userSerialService.getUserSerial();
user$ = this._usersService.getCurrentUser();
data$ = combineLatest([authUser$, serial$, user$]);
data$.subscribe(([loggedInUser, serial, currentUser]) => {
...
});
It can be handy to map the values to an object, so they are easy to retrieve in your template like:
data$ = combineLatest([authUser$, serial$, user$]).pipe(
map(([authUser, serial, user]) => ({authUser, serial, user}))
);
It's also handy if you leverage the async pipe in your template rather than subscribing in your component.
<div *ngIf="data$ | async as data">
<ul>
<li>Current User: {{ data.user }}</li>
<li>Logged in User: {{ data.authUser }}</li>
<li>User Serial: {{ data.serial }}</li>
</ul>
</div>
Upvotes: 1
Reputation: 1778
switchMap
operator takes a function which returns an Observable
, then subscribe to it.
The problem here is that your last switchMap
gets an array instead of an Observable
.
You can use map
instead to transform the data.
this._authService.loggedInUser$.pipe(
switchMap(loggedInUser => this._userSerialService.getUserSerial().pipe(
switchMap(serial => this._usersService.getCurrentUser().pipe(
map(currentUser => [loggedInUser, currentUser, serial]))
)
))
).subscribe(([loggedInUser, currentUser, serial]) => {
...
});
Upvotes: 0