admin管理员组文章数量:1415484
As per the title, I've been trying to figure out a way to make multiple HTTP calls from an action payload and basically merging all results into a single array and then map the result to another action as a payload.
Here is my existing code, it works but it seems it seem not merging both responses and only cares about last response from the request's response, perhaps I'm using the wrong operator, I'm just picking up RxJS and trying different things to learn, hopefully somebody is able to explain where I'm going wrong.
Any help or direction is much appreciated.
{
type: 'FETCH_DATA',
payload: {
key: 'standings',
value: [
'http://url-1',
'http://url-2'
],
})
}
// The epic is listening to the above action
const fetchDataEpic = action$ => action$.pipe(
ofType('FETCH_DATA'),
mergeMap(action => {
const { key, value } = action.payload;
if (Array.isArray(value) && value.length) {
const makeRequest = value.map((x, i) => ajax.getJSON(value[i]))
return (
forkJoin(
makeRequest,
response => {
return ({
type: 'FETCH_DATA_SUCCEEDED',
payload: {
key,
value: response,
},
})
}
)
)
}
})
);
NOTE: Both request's response is in same JSON format with same properties, but different data.
Thanks in advance
As per the title, I've been trying to figure out a way to make multiple HTTP calls from an action payload and basically merging all results into a single array and then map the result to another action as a payload.
Here is my existing code, it works but it seems it seem not merging both responses and only cares about last response from the request's response, perhaps I'm using the wrong operator, I'm just picking up RxJS and trying different things to learn, hopefully somebody is able to explain where I'm going wrong.
Any help or direction is much appreciated.
{
type: 'FETCH_DATA',
payload: {
key: 'standings',
value: [
'http://url-1',
'http://url-2'
],
})
}
// The epic is listening to the above action
const fetchDataEpic = action$ => action$.pipe(
ofType('FETCH_DATA'),
mergeMap(action => {
const { key, value } = action.payload;
if (Array.isArray(value) && value.length) {
const makeRequest = value.map((x, i) => ajax.getJSON(value[i]))
return (
forkJoin(
makeRequest,
response => {
return ({
type: 'FETCH_DATA_SUCCEEDED',
payload: {
key,
value: response,
},
})
}
)
)
}
})
);
NOTE: Both request's response is in same JSON format with same properties, but different data.
Thanks in advance
Share Improve this question asked Oct 14, 2019 at 18:04 FARZADFARZAD 851 silver badge11 bronze badges2 Answers
Reset to default 3it looks like you're using rxjs' ajax function, which should already give you observables. In that case, forkJoin should give you both values as an array once the all the observable have emitted values. And then you can added to your action payload with the map function.
const requestArrays = [1, 2].map(i => {
return rxjs.ajax.ajax.getJSON(`https://jsonplaceholder.typicode./posts/${i}`);
});
rxjs.forkJoin(requestArrays)
.pipe(
rxjs.operators.tap(resp => {
console.log('Part 1: Response so far: ');
console.log(resp);
}),
rxjs.operators.map(value => {
return {
type: 'FETCH_DATA_SUCCEEDED',
payload: {
value
}
};
}),
rxjs.operators.tap(resp => {
console.log('Part 2: Result as a action payload: ');
console.log(resp);
}),
)
.subscribe();
<script src="https://cdnjs.cloudflare./ajax/libs/rxjs/6.5.3/rxjs.umd.min.js"></script>
EDIT: Here is roughly how you would implement it.
const action = {
type: 'FETCH_DATA',
payload: {
value: [
'1',
'2'
],
}
};
rxjs.of(action)
.pipe(
rxjs.operators.mergeMap(action => {
const requestArrays = action.payload.value.map(i => {
return rxjs.ajax.ajax.getJSON(`https://jsonplaceholder.typicode./posts/${i}`);
});
return rxjs.forkJoin(requestArrays)
.pipe(
rxjs.operators.map(value => {
return {type: 'FETCH_DATA_SUCCEEDED', payload: {value}};
})
)
})
)
.subscribe(console.log);
<script src="https://cdnjs.cloudflare./ajax/libs/rxjs/6.5.3/rxjs.umd.min.js"></script>
I don't think it only cares about the last response, but the first one.
That's because if you want to customize the response from forkJoin
, the second(or last, in case the first one isn't an array) argument(which is a function) accepts multiple arguments, which are the responses from the supplied requests.
Thus, this is the change I'd perform in order to get the whole array of responses.
/* ... */
forkJoin(
makeRequest,
(...response) => {
return ({
type: 'FETCH_DATA_SUCCEEDED',
payload: {
key,
value: response,
},
})
}
)
/*
Edit: sending the merged responses to another action
This can be achieved by using the tap operator, which is monly used when you have to deal with side effects.
(
mergeMap(action => { ... }),
tap(action => sendToOtherAction(action))
)
本文标签:
版权声明:本文标题:javascript - How to make multiple HTTP requests with RxJS and merge the response into one payload and map it to another action? 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745232547a2648889.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论