I was planning to call the second api using the data from the first api in my react project i tried using a single useState and chain the promises using axios but it isn't seems to be working as i want to basically filter out the data from the second api based on the first api id value
Api 1
[{
id: 01,
title: Post title One,
external_id: 101
},
{
id: 02,
title: Post title Two,
external_id: 102
},
{
id: 03,
title: Post title Three,
external_id: 103
}]
Api 2
[{
id: 101,
image: Image Url,
},
{
id: 102,
image: Image Url,
},
{
id: 103,
image: Image Url,
}]
I want them to work side by side and then pass them as props to render items based on the data from both the APIs. Here is what i tried i know this code is not correct but i got stuck here. Here is my React code
const App = () => {
const [posts, setPosts] = useState([]);
const [postsExternal, setPostsExternal] = useState([]);
useEffect(() => axios.get(`http://localhost:2000/posts`)
.then(response => {
setPosts(response.data);
return response.data.external_id;
})
.then(getExternalId => axios.get(`http://localhost:2000/posts/${getExternalId}`))
.then(response => {
setPostsExternal(response.data);
}), []);
return (
<div>
<Posts posts={posts} postsExternal={postsExternal}/>
</div>
)
}
export default App
I've read your code and the problem is a little misplaced arrangement of your code. Also because you're getting an array of data and you'd need to make calls using the external_id for every data in that array
I'd suggest you try a different approach. Try the code snippet below (comments included to be better understood):
Thank you.
import React, { useState, useEffect } from "react";
import axios from "axios";
const YourApp = () => {
const [posts, setPosts] = useState([]);
const [postsExternal, setPostsExternal] = useState([]);
useEffect(() => {
// not adding .catch() here for simplicity ๐
axios.get(`http://localhost:2000/posts`).then(({ data }) => {
// we're putting this here because we only want to set state once (we don't wanna have to rerender 30times in data.map())
let externalPosts = [];
// destructed out the {data}, same as response.data, so no worries ๐
setPosts(data);
console.log(data);
// this is where you'll make your second API calls using the external_id from first call
data.map(({ external_id }) => {
// {external_id} same as your-param-name.external_id
axios
.get(`http://localhost:2000/posts/${external_id}`)
.then(({ data }) => {
// we push the data into the array ๐
console.log(data);
externalPosts.push(data);
});
// then finally set the external post states once to prevent multiple rerendring in .map() ๐ฏ
setPostsExternal(externalPosts);
// that's it ๐
});
});
// tho, i'd recommend you create a seperate function for the above ๐
}, []);
return (
<div>
<Posts posts={posts} postsExternal={postsExternal} />
</div>
);
};
export default YourApp;
You are getting an array not an individual object. Modify the useEffect to call the APIs using Promise.all() :
useEffect(() => {
axios.get(`http://localhost:2000/posts`)
.then(response => {
setPosts(response.data);
return response.data.map(({external_id}) => external_id);
})
.then(externalIds => {
return Promise.all(externalIds
.map(externalId => axios.get(`http://localhost:2000/posts/${externalId}`)))
})
.then(response => {
setPostsExternal(response.data);
}),
}, []);