How to call multiple fetch APIs - javascript

I have to make a fetch call at a url and after getting its response I want to use those results to call another fetch. I have following code:-
async function getDate(request) {
let data;
console.log('handle request called')
await fetch('<first-url>')
.then(res => {
let urls = res.json()
console.log('urls are ', urls)
return urls.data
})
.then((urls) => {
let url = urls[0]
console.log('url is ', url)
return fetch(url)
})
.then((res) => {
data = res.body
})
.catch(() => {
console.log("something went wrong")
})
return new Response(data, {
headers: { 'content-type': 'text/html' },
})
}
I followed the above method after following this tutorial. However it does not seem to work and I am getting urls are {Promise:[Pending]}.

Here issue with return res.json(). res.json() is promisable object, so u have to resolve it to get data.
For your example:
const fetch = require("node-fetch");
async function getDate() {
let data;
console.log("handle request called");
return await fetch('<first-url>')
.then((res) => res.json())
.then((urls) => {
console.log("urls are ", urls);
if (urls.length)
return Promise.all(urls.map((url) => fetch(url).then((x) => x.json())));
return [];
})
.then((responses) => {
console.log("urls are ", responses);
return responses;
});
}
getDate().then(console.log);
Sample:
async function getDate() {
let data;
console.log("handle request called");
return await fetch("https://api.covid19api.com/countries")
.then((res) => res.json())
.then((urls) => {
console.log("urls are ", urls);
return urls;
});
}
getDate().then(console.log);

Related

Express.js res.json appending to response object

I'm trying to return some json data using the res.json() function from Express, but instead of returning a new json object each time it seems that it's appending to the old json object each time. This means that I'm receiving duplicate data in the same response object.
My code looks like this:
await Promise.all(promises)
.then(responses => res.json(responses))
.catch(error => console.error(error))
Returned data example:
[
[data]
]
Second request returned data sample:
[
[data],
[data(1)]
]
My code returns a list of responses which I want, but on repeated requests to the same function the new response is appended to the data from the old response and sent back. Is this intended? Am I doing something wrong?
edit: here is the rest of my code for context. I'm new to js and async programming so let me know if something I'm doing is terribly wrong.
const fetch = require('node-fetch')
const authFunctions = require('./auth')
var bearer_token
const space_id = 11111
let id_promises = []
async function get_category_rooms(category_id)
{
return fetch(`https://url.com/api/${category_id}`,
{
headers:
{
'Authorization': `Bearer ${bearer_token}`
}
}).then(response => response.json())
.then(data => data.map(category => category.items))
.catch(err => console.error(err))
}
async function get_category_ids() {
return fetch(`https://url.com/api/${space_id}`,
{
headers:
{
'Authorization': `Bearer ${bearer_token}`
}
})
.then(response => response.json())
.then(data =>
{
categories = data[0]["categories"].filter(category => category.name !== "category i don't want")
categories.forEach(category_item =>
{
id_promises.push(new Promise((resolve, reject) =>
{
resolve(get_category_rooms(category_item.cid))
}))
})
})
}
async function get_room_bookings(room_id) {
return fetch(`https://url.com/api/${room_id}`,
{
headers:
{
'Authorization': `Bearer ${bearer_token}`
}
})
.then(response => response.json())
.then(data => data)
}
async function get_not_group_room_reservations(req,res)
{
let room_promises = []
if (!await authFunctions.auth_check(bearer_token))
{
console.log('invalid bearer token. changing bearer')
bearer_token = await authFunctions.auth()
}
await get_category_ids()
let rooms = await Promise.all(id_promises)
.then(responses =>
{
let room_ids = responses.flat(2)
room_ids.forEach(room_id =>
{
room_promises.push(new Promise((resolve, reject) =>
{
resolve(get_room_bookings(room_id))
}))
})
})
.catch(error => console.error(error))
await Promise.all(room_promises)
.then(responses => res.json(responses))
.catch(error => console.error(error))
}

its passing as combined values 4,5,6

I am new to promise.
I need to make two different api calls.
from the result of first api call I am getting id in the variable firstAPIid,
https://reqres.in/api/users?page=2
I need to pass this id firstAPIid to the second api call.
but the problem is its passing as combined values 4,5,6 https://jsonplaceholder.typicode.com/comments?postId=4,5,6
from the second api call I need to retrieve email and display it in the browser.
do I need to use promise or async or with redux itself can I achieve it.
I researched and referred the below links but still no luck
https://medium.com/#bluepnume/learn-about-promises-before-you-start-using-async-await-eb148164a9c8
can you tell me how to fix it.
providing my code snippet and sandbox below
https://codesandbox.io/s/redux-async-actions-xjdo7
<FetchButton
onFetchClick={() => {
store.dispatch(dispatchFunc => {
dispatchFunc({ type: "FETCH_DATA_START" });
axios
.get("https://reqres.in/api/users?page=2")
// axios.get('https://jsonplaceholder.typicode.com/posts')
.then(response => {
console.log("response.data.data---->", response.data.data);
console.log(
"response.data.data[0].id---->",
response.data.data[0].id
);
dispatchFunc({
type: "RECEIVED_DATA",
payload: response.data.data
});
let firstAPIid = response.data.data.map(obj => {
return obj.id;
});
console.log("firstAPIid---->", firstAPIid);
return new Promise((resolve, reject) => {
//var url = `https://jsonplaceholder.typicode.com/comments?postId=3`;
var url =
`https://jsonplaceholder.typicode.com/comments?postId=` +
firstAPIid;
//response.data.data[0].id;
console.log("second url---->", url);
axios
.get(url)
.then(response => {
var lFilterData = "";
//memberGroupingHelper.filterData(response.data, additionalParams);
resolve(lFilterData);
})
.catch(error => {
if (error.response) {
console.log(
`############## service error from helpeeeeeer reject`
);
}
reject("");
});
});
})
.catch(err => {
dispatchFunc({ type: "FETCH_DATA_ERROR", payload: err });
});
});
}}
/>
I found your issue. It is happening because you are not processing the result of the promise. To do that just add the .then() and .catch() functions:
<FetchButton
onFetchClick={() => {
store.dispatch(dispatchFunc => {
dispatchFunc({ type: "FETCH_DATA_START" });
axios
.get("https://reqres.in/api/users?page=2")
// axios.get('https://jsonplaceholder.typicode.com/posts')
.then(response => {
console.log("response.data.data---->", response.data.data);
console.log(
"response.data.data[0].id---->",
response.data.data[0].id
);
dispatchFunc({
type: "RECEIVED_DATA",
payload: response.data.data
});
let firstAPIid = response.data.data.map(obj => {
return obj.id;
});
console.log("firstAPIid---->", firstAPIid);
return new Promise((resolve, reject) => {
//var url = `https://jsonplaceholder.typicode.com/comments?postId=3`;
var url =
`https://jsonplaceholder.typicode.com/comments?postId=` +
firstAPIid;
//response.data.data[0].id;
console.log("second url---->", url);
axios
.get(url)
.then(response => {
var lFilterData = "";
//memberGroupingHelper.filterData(response.data, additionalParams);
resolve(lFilterData);
})
.catch(error => {
if (error.response) {
console.log(
`############## service error from helpeeeeeer reject`
);
}
reject("");
});
}).then((previousResponse) => {
//Here you resolved the promise with the resolve value above
console.log(previousResponse)
}).catch((error) => {
//Here you resolved the promise with the reject value above
console.log(error);
});
})
.catch(err => {
dispatchFunc({ type: "FETCH_DATA_ERROR", payload: err });
});
});
}}
/>
I am not seeing any use of the Promise because what you want to achieve can be done just with axios.
EDIT:
Just with axios you can get it. Modify as below:
<FetchButton
onFetchClick={() => {
store.dispatch(dispatchFunc => {
dispatchFunc({ type: "FETCH_DATA_START" });
axios
.get("https://reqres.in/api/users?page=2")
// axios.get('https://jsonplaceholder.typicode.com/posts')
.then(response => {
console.log("response.data.data---->", response.data.data);
console.log(
"response.data.data[0].id---->",
response.data.data[0].id
);
//First of all we'll create the number of requestes base on the previous Response
const promises = response.data.data.reduce((previousValue, { id }) => {
previousValue.push(axios.get(`https://jsonplaceholder.typicode.com/comments?postId=${id}`));
return previousValue;
},[]);
//We use the built in function to fetch the data
axios.all(promises)
.then((responses) => {
//Here you have all responses processed
const emailsMapped = responses.reduce((previousValue, { data }) => {
const emails = data.map(({ email }) => email)
previousValue.push(...emails);
return previousValue;
}, [])
//You send the emails you want
dispatchFunc({
type: "RECEIVED_DATA",
payload: emailsMapped
});
console.log(emailsMapped);
})
})
.catch(err => {
dispatchFunc({ type: "FETCH_DATA_ERROR", payload: err });
});
});
}}
/>
Also modifies this line in DataList without the first_name
listItems.push(<div key={fetchedDataId++}>{elem}</div>);

having trouble chaining multiple axios request

Ok, so what I am trying to do is do an axios.get() request pull specific data an id specifically, then use that id that I got to put it as a string literal so I can do my second request. I keep getting Info is not defined.
axios
.get(
`https://na1.api.riotgames.com/lol/summoner/v4/summoners/by-name/bloodstrive?api_key=${api}`
)
.then(response => {
info = response.data.id;
})
.then(
axios.get(
`https://na1.api.riotgames.com/lol/league/v4/entries/by-summoner/${info}?api_key=${api}`
)
)
.then(response => {
summoner = response.data;
return summoner;
});
let getSummonerId = (req, res) => {
res.status(200).send(summoner);
};
module.exports = {
getSummonerId
};
Fix your chaining:
axios
.get(
`https://na1.api.riotgames.com/lol/summoner/v4/summoners/by-name/bloodstrive?api_key=${api}`
)
.then(response => {
return response.data.id;
})
.then(info => {
return axios.get(
`https://na1.api.riotgames.com/lol/league/v4/entries/by-summoner/${info}?api_key=${api}`
)
})
.then(response => {
summoner = response.data;
return summoner;
});
Personally, I recommend async for tasks such as this. Makes handling things a lot easier with promises:
let fetchSummoner = async() => {
const res = await axios.get(`https://na1.api.riotgames.com/lol/summoner/v4/summoners/by-name/bloodstrive?api_key=${api}`);
const info = res.data.id;
const res2 = await axios.get(`https://na1.api.riotgames.com/lol/league/v4/entries/by-summoner/${info}?api_key=${api}`);
const summoner = res2.data;
return summoner;
}
In the current code you haven't added a return statement in the 2nd axios request. Failing to this will not fetch and return the 2nd url.
Please try the below code.
axios
.get(
`https://na1.api.riotgames.com/lol/summoner/v4/summoners/by-name/bloodstrive?api_key=${api}`
)
.then(response => {
return response.data.id;
})
.then(info => {
return axios.get(
`https://na1.api.riotgames.com/lol/league/v4/entries/by-summoner/${info}?api_key=${api}`
)
})
.then(response => {
summoner = response.data;
return summoner;
});

react-native fetch async/await response filtering

I have response from my server like buildings : [record1, record2, ...] and I want to get only the array from that response. How can I get just the array from the Promise? I have tried some async/await things but I didn't understand how to use it in this code:
setupImpagination() {
....
fetch(pageOffset, pageSize, stats) {
return fetch(`http://localhost:3000/api/building/all?skip=${pageOffset}&limit=${pageSize}`)
.then(response => {
console.log('response.json() => ',response.json());
response.json()
})
.catch((error) => {
console.error(error);
});
}
});
}
.then way
fetch(pageOffset, pageSize, stats) {
return fetch(`http://localhost:3000/api/building/all?skip=${pageOffset}&limit=${pageSize}`)
.then(response => {
console.log('response.json() => ',response.json());
response.json()
}).then(responseJson => {
return responseJson.buildings
}).catch((error) => {
console.error(error);
});
}
});
async/await way:
async fetch(pageOffset, pageSize, stats) {
try {
const response = await fetch(`http://localhost:3000/api/building/all?skip=${pageOffset}&limit=${pageSize}`);
const responseJson = await response.json();
return responseJson.buildings;
} catch(error){
console.error(error);
}
async function fetchData (url, { type = 'json' } = {}) {
return await (await fetch(url))[type]();
}
// Example:
(async () => {
console.log(await fetchData('http://canskit.com', { type: 'text' }));
})();
As the original js on ES7, not aim at react-native

How can I format JSON output in javascript

I have this function that fetches a JSON object.
function dataFetch(){
const url = "http://www.quotzzy.co/api/quote?key=436587";
fetch(url).then(function(response) {
return response.text();
}).then(function(text) {
console.log('Request successful', text);
}).catch(function(error) {
log('Request failed', error)
});
};
How can I return the indices in the JSON object individually to use in HTML?
Like, my name (object.name) and my quote is (object.text) from this source (object.source).
Use json() on the response. It returns a promise for the object.
function dataFetch(){
const url = "http://www.quotzzy.co/api/quote?key=436587";
fetch(url)
.then(function(response) {
return response.json();
})
.then(function(json) {
console.log(json.author.name);
});
.catch(function(error) {
log('Request failed', error)
});
}
More idiomatic:
function dataFetch(){
const url = "http://www.quotzzy.co/api/quote?key=436587";
fetch(url)
.then(response => response.json())
.then(json => console.log(json.author.name, "said", json.text))
.catch(error => log('Request failed', error));
}
You can directly use the json() method of the Response object in this manner.
function dataFetch(){
const url = "http://www.quotzzy.co/api/quote?key=436587";
fetch(url)
.then(function(response) {
if(response.status == 200){
return response.json();
})
.then(function(responseObj) {
var text = responseObj.text;
var authorName = responseObj.author.name;
var source = responseObj.author.wiki;
...//access all attributes from the json
...//assign them to HTML elements
})
.catch(function(error) {
log('Request failed', error)
});
};
You can use response.json() to convert your response as JSON object. The response.json() method returns a promise. You will resolve promise you can get JSON object.
function dataFetch(){
const url = "http://www.quotzzy.co/api/quote?key=436587";
fetch(url)
.then(function(response) {
// return response.text(); // wrong
return response.json(); // right
})
.then(function(json) {
console.log('Request successful', json);
})
.catch(function(error) {
log('Request failed', error)
});
};

Categories