I have 'nested' requests, team creation and team avatar uploading, wherein second depends on first and should be sent only if avatar is not null (I've already done this using filter operator). What I need now is to get access to both responses in subscribe method.
this.team.createTeam(teamRequest)
.pipe(
filter(() => avatar),
flatMap(next => this.team.uploadLogo(avatar, next.body.uuid)
).subscribe(responses => {
// so, I want response from both createTeam and uploadLogo in responses
});
You could pipe in a map
operator to the inner request and send both the responses. Try the following
this.team.createTeam(teamRequest)
.pipe(
filter(() => avatar),
flatMap(next =>
this.team.uploadLogo(avatar, next.body.uuid).pipe(
map(res => ({ avatar: res, team: next }))
)
)
).subscribe(responses => {
// responses.avatar: response from `this.team.uploadLogo(avatar, next.body.uuid)`
// responses.team: response from `this.team.createTeam(teamRequest)`
});
I've returned an object for illustration. You could return it in any form as per your requirement. Eg. as an array map(res => [ next, res ]))
.
iif
function instead of filter
operatorIf you still want to subscribe to the source observable when the filter
condition fails, the quickest way I could think of is to forgo the filter
operator and use iif
function instead. Try the following
const upload = (avatar, team): Observable<any> => {
return this.team.uploadLogo(avatar, next.body.uuid).pipe(
map(res => ({ avatar: avatar, team: team }))
);
};
iif(() =>
!!avatar,
this.team.createTeam(teamRequest).pipe(flatMap(next => upload(avatar, next.body.uuid))),
this.team.createTeam(teamRequest)
).subscribe(
responses => {
// if `avatar` is null
// responses: response from `this.team.createTeam(teamRequest)`
// or
// if `avatar` is non-null
// responses.avatar: response from `this.team.uploadLogo(avatar, next.body.uuid)`
// responses.team: response from `this.team.createTeam(teamRequest)`
}
);
avatar
inside the flatMap
As suggested by @bryan60, here is a more cleaner code that uses neither filter
nor iif
. But rather checks avatar
inside the flatMap
and returns of(next)
if it's null.
this.team.createTeam(teamRequest).pipe(
flatMap(next => {
if (!!avatar) {
return this.team.uploadLogo(avatar, next.body.uuid).pipe(
map(res => ({ avatar: res, team: next }))
);
}
return of(next);
})
).subscribe(responses => {
// if `avatar` is null
// responses: response from `this.team.createTeam(teamRequest)`
// or
// if `avatar` is non-null
// responses.avatar: response from `this.team.uploadLogo(avatar, next.body.uuid)`
// responses.team: response from `this.team.createTeam(teamRequest)`
});