I have an Observable
in which I consume another observable, but the 2nd Observable
I can't get to resolve. Here is the code:
return Observable.fromPromise(axios(config))
.map(res => {
return {
accessToken: res.data.access_token,
refreshToken: res.data.refresh_token
}
})
.map(res => {
return {
me: getMe(res.accessToken),
accessToken: res.accessToken,
refreshToken: res.refreshToken
}
})
function getMe(accessToken) {
return Observable.fromPromise(axios.get({
url: '',
}));
}
The getMe
function returns an Observable
, but it is never resolved. I have tried to add a flatMap
and a concat
, but it still isn't resolved. How do I get the getMe
to resolve?
I have an Observable
in which I consume another observable, but the 2nd Observable
I can't get to resolve. Here is the code:
return Observable.fromPromise(axios(config))
.map(res => {
return {
accessToken: res.data.access_token,
refreshToken: res.data.refresh_token
}
})
.map(res => {
return {
me: getMe(res.accessToken),
accessToken: res.accessToken,
refreshToken: res.refreshToken
}
})
function getMe(accessToken) {
return Observable.fromPromise(axios.get({
url: 'https://api.spotify.com/v1/me',
}));
}
The getMe
function returns an Observable
, but it is never resolved. I have tried to add a flatMap
and a concat
, but it still isn't resolved. How do I get the getMe
to resolve?
3 Answers
Reset to default 12Did you try the following (Also untested):
function getMe(accessToken) {
return Rx.Observable.fromPromise(axios.get({
url: 'https://api.spotify.com/v1/me',
}));
}
Rx.Observable.fromPromise(axios(config))
.map((res) => {
return {
accessToken: res.data.access_token,
refreshToken: res.data.refresh_token
}
})
.flatMap((res) => {
return getMe(res.accessToken).map((res2) => {
res.me = res2;
return res;
}
})
.subscribe((data) => console.log(data));
As mentioned in the above post, flatMap
returns an observable. map
is subsequently used to merge res
with the result res2
returned from the second promise.
Also note that fromPromise
is a cold observable. This means that you must have a subscription to initiate things. In your case, I presume you already have something like this:
someFunction = () => {
return Rx.Observable.fromPromise(axios(config))
...
...
}
someFunction.subscribe((data) => console.log(data));
As @user3743222 pointed out, an Observable
does not resolve
in the sense that a Promise
does. If you want the value you of the getMe
method you will need to subscribe to the Observable
returned by it.
return Observable.fromPromise(axios(config))
.map(res => {
return {
accessToken: res.data.access_token,
refreshToken: res.data.refresh_token
}
})
.flatMap(function(tokens) {
//FlatMap can implicitly accept a Promise return, so I showed that here
//for brevity
return axios.get({url : 'https://api.spotify.com/v1/me'});
},
//The second method gives you both the item passed into the first function
//paired with every item emitted from the returned Observable`
//i.e. axios.get(...)
function(tokens, response) {
return {
accessToken: tokens.accessToken,
refreshToken: tokens.accessToken,
//Here response is a value not an Observable
me: response
};
});
Sample code to find below (UNTESTED!!). Some explanations :
- the observable returned by
getMe
is not flattened ('resolve' belong to the world of promises) because themap
operator does not flatten observables.flatMap
do, but you need to use it in the formsource.flatMap(function(x){return observable})
and here what you return is aPOJO
not aRx.Observable
. - So, to flatten the
getMe
we use aflatMap
. - To add back the missing fields (
accessToken
andrefreshToken
) we usewithLatestFrom
on the observable who emitted theres
object (res$
). We use
share
as we subscribe twice tores$
, and we want all subscribers to see the same values.var res$ = Observable .fromPromise(axios(config)) .map(function ( res ) { return { accessToken : res.data.access_token, refreshToken : res.data.refresh_token } }) .share(); var getMe$ = res$.flatMap(function ( res ) {return getMe(res.accessToken)}); var finalRes$ = getMe$.withLatestFrom(res$, function ( getMe, res ) { return { me : getMe, accessToken : res.accessToken, refreshToken : res.refreshToken } }); function getMe ( accessToken ) { return Observable.fromPromise(axios.get({url : 'https://api.spotify.com/v1/me'})); }