Hello I’m new to Javascript and APIs.
But I have an excersise where I should get Data from.
The problem is that it doesn’t list all the planets at once so that URL only shows the first 10 entries while https://swapi.co/api/planets/?page=2 shows the next and so on.
This is my current code, it works but I don’t think I’m going as I’m supposed to so I wonder how you would solve this problem.
https://codepen.io/indiehjaerta/pen/QQXVJX
var starWarsAPI = new StarWarsAPI(); starWarsAPI.Initialize(); function StarWarsAPI() { this.planets = new Array(); this.Initialize = function() { this.LoadPlanets("https://swapi.co/api/planets"); } this.LoadPlanets = function(aURL) { fetch(aURL).then( function (response) { if (response.status !== 200) { console.log('Looks like there was a problem. Status Code: ' + response.status); return; } response.json().then( data => this.LoadPlanetsRecursive(data) ); }.bind(this) ).catch(function (err) { console.log('Fetch Error :-S', err); }); } this.LoadPlanetsRecursive = function(aData) { for (let planet of aData.results) { let newPlanet = new Planet(planet); this.planets.push(newPlanet); } if (aData.next != null) { fetch(aData.next).then( function (response) { if (response.status !== 200) { console.log('Looks like there was a problem. Status Code: ' + response.status); return; } response.json().then( data => this.LoadPlanetsRecursive(data) ); }.bind(this) ).catch(function (err) { console.log('Fetch Error :-S', err); }); } } this.PresentPlanetsInHTML = function() { } } function Planet(aPlanet) { this.name = aPlanet.name; console.log(this); }
2nd question is where I should put my “PresentData” so I know that all planets have been loaded and not 1 by 1 when the’re added to the array.
Advertisement
Answer
You could recursively create a promise resolve chain. A bit less repetition and you’ll know when all planets are loaded when the parent promise resolves.
function getStarWarsPlanets(progress, url = 'https://swapi.co/api/planets', planets = []) { return new Promise((resolve, reject) => fetch(url) .then(response => { if (response.status !== 200) { throw `${response.status}: ${response.statusText}`; } response.json().then(data => { planets = planets.concat(data.results); if(data.next) { progress && progress(planets); getStarWarsPlanets(progress, data.next, planets).then(resolve).catch(reject) } else { resolve(planets); } }).catch(reject); }).catch(reject)); } function progressCallback(planets) { // render progress console.log(`${planets.length} loaded`); } getStarWarsPlanets(progressCallback) .then(planets => { // all planets have been loaded console.log(planets.map(p => p.name)) }) .catch(console.error);