Reputation: 1386
I'm relatively new to rxjs and Observables. I'm trying to write a service method which returns an observable that when subscribed, will output the result of an HTTP request. However, before I can make the request, I have to ensure the proper authorization token is present (it won't always be there).
Here's the way I came up with to accomplish this task:
getDataFromHTTPCall (): Observable<any> {
return new Observable(subscriber => {
if (this.authorizationToken == null) {
subscriber.error("Authorization Token Required")
} else {
subscriber.next(
from(
axios.get(`${this.baseUrl}/getData}`, { headers: {'Authorization': this.authorizationToken }})
).pipe(
map(result => result.data),
catchError( (err) => {
console.log(err)
return EMPTY
})
)
)
}
})
}
This technically works, but it has some major issues. Most notably, by passing an observable to an observable, it requires the caller of this function to subscribe twice. I've been reading that observables should never be nested like this, I can see why this wouldn't be desired.
I get the feeling there's a better way to accomplish what I'm trying to do here. Could someone advise on a better way to accomplish this kind of task using observables?
Upvotes: 0
Views: 235
Reputation: 14679
The logic of the function sounds like "If you don't have stored credentials, throw error, otherwise return the axios call put through some pipe". Translated to RxJS, it could look like this:
getDataFromHTTPCall(): Observable<any> {
return this.authorizationToken == null
? throwError('Authorization Token Required')
: from(
axios.get(`${this.baseUrl}/getData}`, {
headers: {Authorization: this.authorizationToken},
}).pipe(/* etc */)
);
}
Upvotes: 2
Reputation: 17762
What about starting with emitting the value of this.authorizationToken
and then using concatMap
to call the http service or error if this.authorizationToken
is null?
The code would look something like this
getDataFromHTTPCall() {
return of(this.authorizationToken).pipe(
concatMap(authToken => {
if (authToken == null) {
throw new Error("Authorization Token Required")
}
return from(axios.get(`${this.baseUrl}/getData}`,
{ headers: {'Authorization': authToken }})
).pipe(
map(result => result.data),
catchError( (err) => {
console.log(err)
return EMPTY
})
)
})
)
}
Upvotes: 1