I am trying to call the API in sequential order and I will use the previous response for the next API call. And I will be having the N number of API calls, Lets consider below is my sample array I have,
data = [
{
api: '/api/allGeneTables/',
},
{
api: '/api/tables/',
fieldName: 'profiles', // I am using this for building api
concatWithPrevField: true,
prevField: 'positions' // I am using this for building api
},
{
api: '/api/tables/superpositions',
fieldName: 'identical', // I am using this for building api
concatWithPrevField: true,
prevField: 'length' // I am using this for building api
}
]
First API will produce the data like this
https://myurl/api/allGeneTables/
API Response:
{
'positions': 10,
'index': 12,
'name': 'triosephaspate'
}
I need to create the next api with the previous value (positions) along with given fieldName (profiles), so the the second api would be
https://myurl/api/tables/10/profiles
// 10 came from the previous response value (positions)
// profiles is one of field's value of the current array
API Response:
{
'lipidprofile': 15,
'maxvalue': 12,
'name': 'triosephaspate',
'length':232
}
similar way I need to create the next API.
https://myurl/api/tables/superpositions/232/identical
// 232 came from the previous response value (length)
// identical is one of field's value of the current array
I have tried with the map operator and following is my code
from(data).pipe(map(res => {
const eachObj: any = res;
let urlConcat = '';
console.log(res);
if (eachObj.concatWithPrevField) {
// urlConcat = eachObj.api + ;
} else {
urlConcat = eachObj.api;
}
return this.dhs.getGeneData(urlConcat).subscribe();
})).subscribe();
I stuck at, how to join the previous API response value with the current data to make the API URL so I can call the next API. I am trying this with the RXJS methods.
last_result
).concatMap
to wait for the API calls being completed before the next one is initiated and use the new value in last_result
.reduce
to complete the observable stream and emit the latest API-response (last_result
).Stackblitz: https://stackblitz.com/edit/rxjs-v5pg4n?file=index.ts
import { from, interval } from "rxjs";
import { concatMap, map, reduce, take } from "rxjs/operators";
const data_source = [
{
api: "/api/allGeneTables/"
},
{
api: "/api/tables/",
fieldName: "profiles", // I am using this for building api
concatWithPrevField: true,
prevField: "positions" // I am using this for building api
},
{
api: "/api/tables/superpositions/",
fieldName: "identical", // I am using this for building api
concatWithPrevField: true,
prevField: "length" // I am using this for building api
}
];
call_sequence(data_source).subscribe(console.log);
function call_sequence(data) {
let last_result = null;
return from(data).pipe(
// concatmap awaits finishing of request ( last_result is being set and emits the API response)
concatMap(fake_fetch),
// reduce only emit last result from the stream
reduce(() => last_result)
);
function fake_fetch(data) {
let endpoint = data.api;
if (data.concatWithPrevField) {
endpoint = endpoint.concat(`${last_result[data.prevField]}`);
endpoint = endpoint.concat(`/${data.fieldName}`);
}
return fake_API_call(endpoint).pipe(
map(data => {
last_result = data;
return data;
})
);
}
}
function fake_API_call(endpoint) {
console.log(`making API call to ${endpoint}`);
return interval(1000).pipe(
take(1),
map(data => {
switch (endpoint) {
case "/api/allGeneTables/":
return {
positions: 10,
index: 12,
name: "triosephaspate"
};
case "/api/tables/10/profiles":
return {
lipidprofile: 15,
maxvalue: 12,
name: "triosephaspate",
length: 232
};
case "/api/tables/superpositions/232/identical":
return "Hurray, I am the final result";
default:
console.error("This endpoint doesn't exist");
}
})
);
}
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments