I want to get an api and after that call another one. Is it wisely using a code like this in javascript?
fetch(url, {
method: \'get\',
}).then(function(res
This is a common question people get tripped up by when starting with Promises, myself included when I began. However, first...
It's great you're trying to use the new Fetch API, but if I were you I would use a XMLHttpRequest implementation for now, like jQuery AJAX or Backbone's overridden implementation of jQuery's .ajax()
, if you're already using these libraries. The reason is because the Fetch API is still so new, and therefore experimental at this stage.
With that said, people definitely do use it, but I won't in my own production code until it's out of "experimental" status.
If you decide to continue using fetch
, there is a polyfill available. NOTE: you have to jump through extra hoops to get error handling to work properly, and to receive cookies from the server. If you're already loading jQuery, or using Backbone, just stick with those for now; not completely dreadful, anyway.
You want a flat structure, else you're missing the point of Promises. It's not wise to nest promises, necessarily, because Promises solve what nested async callbacks (callback hell) could not.
You will save yourself time and energy, and produce less buggy code by simply using a more readable code structure. It's not everything, but it's part of the game, so to speak.
Promises are about making asynchronous code retain most of the lost properties of synchronous code such as flat indentation and one exception channel.
-- Petka Antonov (Bluebird Promise Library)
// run async #1
asyncGetFn()
// first 'then' - execute more async code as an arg, or just accept results
// and do some other ops
.then(response => {
// ...operate on response data...or pass data onto next promise, if needed
})
// run async #2
.then(asyncGetAnotherFn)
.then(response => {
// ...operate on response data...or pass data onto next promise, if needed
})
// flat promise chain, followed by 'catch'
// this is sexy error handling for every 'then' above
.catch(err => {
console.error('Request failed', err)
// ...raise exeption...
// ... or, retry promise...
})
There is not an issue with nesting fetch()
calls. It depends on what you are trying to achieve by nesting the calls.
You can alternatively use .then()
to chain the calls. See also How to structure nested Promises
fetch(url)
.then(function(response) {
return response.json()
})
.then(function(data) {
// do stuff with `data`, call second `fetch`
return fetch(data.anotherUrl)
})
.then(function(response) {
return response.json();
})
.then(function(data) {
// do stuff with `data`
})
.catch(function(error) {
console.log('Requestfailed', error)
});
Fetch returns a promise, and you can chain multiple promises, and use the result of the 1st request in the 2nd request, and so on.
This example uses the SpaceX API to get the info of the latest launch, find the rocket's id, and fetch the rocket's info.
var url = 'https://api.spacexdata.com/v2/launches/latest';
var result = fetch(url, {
method: 'get',
}).then(function(response) {
return response.json(); // pass the data as promise to next then block
}).then(function(data) {
var rocketId = data.rocket.rocket_id;
console.log(rocketId, '\n');
return fetch('https://api.spacexdata.com/v2/rockets/' + rocketId); // make a 2nd request and return a promise
})
.then(function(response) {
return response.json();
})
.catch(function(error) {
console.log('Request failed', error)
})
// I'm using the result variable to show that you can continue to extend the chain from the returned promise
result.then(function(r) {
console.log(r); // 2nd request result
});
.as-console-wrapper { max-height: 100% !important; top: 0; }