Hans Felix Ramos
Hans Felix Ramos

Reputation: 4434

Conditional fetch chaining in javascript

I want to fill an object geoInfo getting data from 3 endpoints using fetch, initial object is like:

let geoInfo = {
    ip: null,
    user: null,
    country: null
};

I will call this function many times, thats why I want to add conditions: if geoInfo.ip is set, it musn´t run the first fetch and if geoInfo.user is set, it musn´t run the second fetch too. How Can I handle this?

let geoInfo = {
  ip: null,
  user: null,
  country: null
};

// Get user info based on ip.
function getGeoInfo() {
  return new Promise((resolve, reject) => {

    let result = fetch('https://api.ipify.org?format=json')
      .then(function(response) {
        return response.json();
      })
      .then(function(data) {
        geoInfo.ip = data.ip;
        return fetch('https://www.iplocate.io/api/lookup/' + geoInfo.ip);
      })
      .then(function(response) {
        return response.json();
      })
      .then(function(data) {
        geoInfo.user = data;
        return fetch('https://restcountries.eu/rest/v2/alpha/' + geoInfo.user.country_code);
      })
      .then(function(response) {
        return response.json();
      })
      .then(function(data) {
        geoInfo.country = data;
      })
      .catch(function(error) {
        console.log('Request failed', error);
        reject(error);
      })

    result.then(function(response) {
      resolve(geoInfo);
    });
  });
}

getGeoInfo().then(res => console.log(res)).catch(err => console.log(err));

Upvotes: 1

Views: 2255

Answers (2)

Dan Knights
Dan Knights

Reputation: 8378

You can chain subsequent fetch requests inside .then and add conditionals based off whether the previous data has been set:

.then(function(data) { 
    geoInfo.ip = data.ip; 
    return fetch('https://www.iplocate.io/api/lookup/' + geoInfo.ip)
        .then(function(data) { 
            if (geoInfo.ip) return;
            return fetch('...and so on')
        }); 
})

Upvotes: 1

Krzysztof Krzeszewski
Krzysztof Krzeszewski

Reputation: 6749

Simple check for the value should be enough, you check if it's been set before, and if not you assign a new value to it. Here is an example using async/await

let geoInfo = {
  ip: null,
  user: null,
  country: null
};

async function getGeoInfo() {
    geoInfo.ip = geoInfo.ip || (await fetch('https://api.ipify.org?format=json').then(res => res.json())).ip;
    geoInfo.user = geoInfo.user || (await fetch('https://www.iplocate.io/api/lookup/' + geoInfo.ip).then(res => res.json()));
    geoInfo.country = geoInfo.country || (await fetch('https://restcountries.eu/rest/v2/alpha/' + geoInfo.user.country_code).then(res => res.json()));
    return geoInfo;
}

getGeoInfo().then(res => console.log(res)).catch(err => console.log(err));

Upvotes: 2

Related Questions