Calling React js Fetch Calls In a Sequence - javascript

Someone, please help me to call these fetch Api's one after the other as I am using the data which is stored in the backend for my next request. I want them to be called sequentially one complete then next request this way.
Promise.all([
fetch(`http://localhost:5000/zoomapi`,
requestOptions),
fetch('http://localhost:5000/getId')
.then((res) => res.json())
.then((result) => {
this.setState({ zoomid: result });
}),
fetch(`http://localhost:5000/users/zoom?name=${this.state.zoomid}`)
.then((res) => res.json())
.then((result) => {
this.setState({ zoomdata: result });
})
])
.catch((error) => {
this.setState({ error });
});
})

.setState is not a synchronous operation, so you cannot use const id = this.state.zoomid, you can use result instead. In addition, your promises should be chained, not nested. Example:
fetch('http://localhost:5000/getId')
.then((res) => res.json())
.then((result) => {
this.setState({ zoomid: result });
return fetch(`http://localhost:5000/users/zoom?name=${result}`);
})
.then((res) => res.json())
.then((result) => {
this.setState({ zoomdata: result });
})
.catch((error) => {
this.setState({ error });
});

Related

How to fetch data from api?

I want to fetch data (particularly market cap)from api and display it inside my div. But my html diplays no data on execution. What could I be doing wrong?
<text id="result"></text>
<script>
// API for get requests
let fetchRes = fetch(
"https://api.lunarcrush.com/v2?data=assets&key=n8dyddsipg5611qg6bst9&symbol=AVAX");
// fetchRes is the promise to resolve
// it by using.then() method
fetchRes.then((res) => res.json())
.then((result) => {
console.log(result);
document.getElementById('result').innerHTML = result.config.data.0.market_cap;
})
.catch(error => {
console.log(error);
})
</script>
Two suggestions:
Why not just chain the .then() directly to the fetch()?
You seem to have a bit of confusion on how to access the data in your structure - what you're after is result.data[0].market_cap.
// API for get requests
let fetchRes = fetch("https://api.lunarcrush.com/v2?data=assets&key=n8dyddsipg5611qg6bst9&symbol=AVAX")
.then((res) => res.json())
.then((result) => {
console.log(result);
document.getElementById('result').innerHTML = result.data[0].market_cap;
})
.catch(error => {
console.log(error);
})
<text id="result"></text>
Aside: you should probably invalidate your API key that you've included here, as it's now out in public and can be used to forge requests as you to this API.
I am using jQuery Framework to do this easily.
Check the code below.
<script>
$.get(
"https://api.lunarcrush.com/v2",
{
data: "assets",
key: "n8dyddsipg5611qg6bst9",
symbol: "AVAX"
},
function (result){
data = JSON.parse(result);
}
);
</script>
You can use jQuery by adding the following code in your <head> tag.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
Use result.config.data[0].market_cap; instead of result.config.data.0.market_cap;
let fetchRes = fetch(
"https://api.lunarcrush.com/v2?data=assets&key=n8dyddsipg5611qg6bst9&symbol=AVAX");
// fetchRes is the promise to resolve
// it by using.then() method
fetchRes.then((res) => res.json())
.then((result) => {
console.log(result);
document.getElementById('result').innerHTML = result.config.data[0].market_cap;
})
.catch(error => {
console.log(error);
});
You can make it cleaner and simpler:
const fetchData = async(url) => (await fetch(url)).json();
fetchData("https://api.lunarcrush.com/v2?data=assets&key=n8dyddsipg5611qg6bst9&symbol=AVAX")
.then(res => {
result.innerText = res.data[0].market_cap;
})
.catch(err => {
console.log(err);
});
<text id="result"></text>

How to resolve multiple then() promise into one

In this code I used multiple then() methods, I just want to convert it into only one then, How it is possible.
getGreeting = () => {
fetch(url)
.then((response) => response.json())
.then((result) => result.data)
.then((data) => printCards(data))
.catch((err) => {
console.log(err);
});
};
notice the async and await keywords
fetch(url)
.then(async (response) => {
const json = await response.json();
printCards(json.data);
})
.catch((err) => {
console.log(err);
});
};

What would this code look like if instead of "async/await" use "then and catch"?

There is such a method in a React application:
fetchData = async () => {
try {
const response = await fetch(`https://........`);
const data = (await response.json()).group;
this.setState({
data: data,
car: Object.keys(data)[0]
},this.filter);
} catch(err) {
console.log("404 Not Found");
}
};
How to write this part without async / await syntax, and using then and catch?
Just like this!
fetchData = () => {
fetch("YOUR_URL")
.then(response => response.json())
.then(json => json.group)
.then(data => {
this.setState({
data,
car: Object.keys(data)[0]
},this.filter);
})
.catch(err => {
console.log("404 Not Found");
});
}
It's simply-
fetchData = () => {
fetch(url)
.then(res => res.json())
.then(data => {
this.setState({data: data.group, car: Object.keys(data.group)[0]})
})
.catch(err => console.log(err));
};
If fetch returns a Promise you can:
fetchData = () => {
fetch(url)
.then(res => ... )
.catch(err => ...)
};
fetchData = () => {
return fetch(`https://........`)
.then(response => {
const data = response.json().group;
this.setState({
data: data,
car: Object.keys(data)[0]
},this.filter);
}).catch(err => {
console.log("404 Not Found");
});
};
response.json() won't return a Promise so you don't need await

How to fetch data from multiple db from the node.js in frontend react.js

I have the below code, where I have to get data from all the files in the same DB. Node.js is running at the backend. When I try the below code, I always get the last fetch, can anyone please help me how to fix this.
The below is from the react JS frontend.
componentDidMount() {
console.log("This Worked Sucessfully")
this.getDataFromDb();
if (!this.state.intervalIsSet) {
let interval = setInterval(this.getDataFromDb, 1000);
this.setState({ intervalIsSet: interval });
}
}
getDataFromDb = () => {fetch('http://172.24.78.202:3001/api/passed')
.then(data => data.json())
.then(res => this.setState({ passed: res.data }));
};
getDataFromDb = () => {fetch('http://172.24.78.202:3001/api/failed')
.then(data => data.json())
.then(res => this.setState({ failed: res.data }));
};
getDataFromDb = () => {fetch('http://172.24.78.202:3001/api/all')
.then(data => data.json())
.then(res => this.setState({ data2: res.data }));
};
render() {
const primaryColor = getColor('primary');
const secondaryColor = getColor('secondary');
const { passed, failed, data2 } = this.state
From what I see by your code, you seem to be re-writing your goGetDataFromDB two times. Try changing the names of each function or, the way you call them. You can also take advantage of Promise.all to group the results of each call into a single return handle.
Check this link for the documentation of Promise.all
You could refactor your current code to something like this:
class MyComponent extends React.Component {
componentDidMount() {
this.getDataFromDb();
if (!this.state.intervalIsSet) {
let interval = setInterval(this.getDataFromDb, 1000)
this.setState({intervalIsSet: true })
}
}
getDataFromDb = () => {
Promise.all([
'http://172.24.78.202:3001/api/passed',
'http://172.24.78.202:3001/api/failed',
'http://172.24.78.202:3001/api/all'
].map(url => (
fetch(url)
.then(data => data.json())
.then(res => res.data)
)
)).then(([passed, failed, data2]) =>
this.setState({ passed, failed, data2 })
);
}
render() {
//...
}
}
I tried to keep as much as your code as possible so you could notice the differences.
I hope this helps.

React/FetchAPI: How to take data from related json by id

I want to take data from JSON, next take another data from related JSON by ID and push it to my state array movies.
This is my code:
state = {
movies: []
}
componentDidMount() {
fetch('https://api.themoviedb.org/3/movie/popular?api_key=APIKEY&page=1')
.then(response => response.json())
.then(data => {
const movies = data.results;
movies.forEach(movie => this.moviePageAndGenres(movie.id, movie));
this.setState({
movies
});
})
}
moviePageAndGenres = (id, element) => {
fetch('https://api.themoviedb.org/3/movie/' + id + '?api_key=APIKEY')
.then(response => response.json())
.then(data => {
element.genres = data.genres;
element.homepage = data.homepage;
});
}
In render() I just console.log my movies to check if data inside is correct.
Output:
image
So it's correct but when I check Component Props these props are not transferred.
image
This is how I transfer props:
const movies = this.state.movies.map(movie =>
<Movie genres={movie.genres}
homepage={movie.homepage}
key={movie.id}
title={movie.title}
poster={movie.poster_path}
rating={movie.vote_average}
/>
)
I guess it's problem with multiple call of asynchronousfetch(). But i don't know how to handle with it.
The reason its not working is, you are firing multiple fetch calls which are async and setting the state immediately after it. setState will get empty movies in that case.
fetch api returns a promise and you should set your state in promise resolution handler. Modify your componentDidMount like this.
componentDidMount() {
fetch('https://api.themoviedb.org/3/movie/popular?api_key=APIKEY&page=1')
.then(response => response.json())
.then(data => {
const movies = data.results;
Promise.all(movies.map(movie => fetch(
`https://api.themoviedb.org/3/movie/${movie.id}?api_key=APIKEY`
)))
.then(resp => Promise.all( resp.map(r => r.json()) ))
.then(result => {
const movies = result.map((data, i) => {
const movie = Object.assign(movies[i], {
genres: data.genres,
homepage: data.homepage
});
return movie;
});
this.setState({
movies
});
});
})
}
You need async await in this case and it’s good to use Promise.all because you are doing fetch in forEach.
For forEach you need await Promise.all and for fetch you need await. Which mean it will wait until the forEach is completed
Change
fetch('https://api.themoviedb.org/3/movie/popular?api_key=APIKEY&page=1')
.then(response => response.json())
.then(data => {
const movies = data.results;
movies.forEach(movie => this.moviePageAndGenres(movie.id, movie));
this.setState({
movies
});
})
To
fetch('https://api.themoviedb.org/3/movie/popular?api_key=APIKEY&page=1')
.then(response => response.json())
.then(async data => {
const movies = data.results;
await Promise.all(movies.forEach(async movie => await this.moviePageAndGenres(movie.id, movie)))
this.setState({
movies
});
})
Also
Change
moviePageAndGenres = (id, element) => {
fetch('https://api.themoviedb.org/3/movie/' + id + '?api_key=APIKEY')
.then(response => response.json())
.then(data => {
element.genres = data.genres;
element.homepage = data.homepage;
});
}
To
moviePageAndGenres = async (id, element) => {
return await fetch('https://api.themoviedb.org/3/movie/' + id + '?api_key=APIKEY')
.then(response => response.json())
.then(data => {
element.genres = data.genres;
element.homepage = data.homepage;
});
}

Categories