Home > other >  StarWars API: Create buttons to move between planet pages
StarWars API: Create buttons to move between planet pages

Time:10-13

I'm using the very famous StarWars API and I should extrapolate the data from the first page of the planets (and so far I have no problems). Sure, I had to do some research to figure out how to do it, but I finally succeeded. But now there is another problem.

I would have to create buttons that allow the user to go to the second page of the planets and get data from that page. And here I am stuck, because I don't know how to do it, because then, using the Next Button, the user must be able to go to the third,, fourth, fifth and sixth page, and then returning back to the first page of planets.

So I looked at the URL and thought we could bind a variable to it that is itself bound to a value provided by the buttons. In this way, if the user clicks on the button the chosen value should be given to the variable located after the URL. To do this I used the value and --value patterns, which do what they should: increase and decrease the value.

However, this is not transmitted to the URL and the new fetch process does not take place to get the info from the pages. But I did something wrong and I don't know what.

Could you please help me? ..

This is the problematic code:

  value = 1

  const prevButton = document.createElement("button");
  prevButton.innerText = 'Prev Page'
  prevButton.setAttribute("id", "prev-button")
  document.body.append(prevButton);
  prevButton.style.cssText = "background-color: violet; width: 150px; height: 45px; 
 transform: translateY(-725%); margin-left: -10px;"
  prevButton.addEventListener('click', () => {
  return --value
  })
 
  const nextButton = document.createElement("button");
  nextButton.innerText = 'Next Page'
  nextButton.setAttribute("id", "next-button")
  document.body.append(nextButton);
  nextButton.style.cssText = "background-color: violet; width: 150px; height: 45px; transform: translateY(-825%); margin-left: 90.5%;"
  nextButton.addEventListener('click', () => {
   return   value
  })


    const response = await fetch ('https://swapi.dev/api/planets/?page='   value);
    const planetsData = await response.json().then(planetsData => {
    let results = planetsData.results;
    results.forEach(planet => {
    const wrapper = document.createElement("wrapper")
    square.append(wrapper);
    wrapper.style.cssText = 'background-color: red; width: 200px; height: 250px; margin: auto; margin-top: 1.5%; margin-left: 50px; display: flex; flex-wrap: nowrap"; flex-direction: row;'
    wrapper.innerHTML = '<div><h1>Name: '   planet.name   '</h1>'   
    '<h3><p>Climate: '   planet.climate   '</p></h3>'   
    '<p>Population: '   planet.population   
    '<p>Terrain: '   planet.terrain    '</p></div>';
   });
   }) 

CodePudding user response:

Here's an example that embellishes on my comment. I've hardcoded the buttons here for convenience but the key points are:

  1. getting that fetch process in its own function so that it can be called whenever a button is clicked

  2. Using the next and previous properties of the returned data to guide which page should be displayed next.

// Cache the elements
const planets = document.querySelector('.planets');
const buttons = document.querySelector('.buttons');
const previous = document.querySelector('[data-id="previous"]');
const next = document.querySelector('[data-id="next"]');

// Add one listener to the button container
buttons.addEventListener('click', handleClick);

// Initialise the base endpoint, and `data`
const base = 'https://swapi.dev/api/planets/?page=1';
let data = {};

// Fetch the first page
fetchData();

// When a button is clicked grab its
// data id (which will be either "previous" or "next"
// and use that to fetch the next page
function handleClick(e) {
  if (e.target.matches('.button')) {
    const { id } = e.target.dataset;
    fetchData(id);
  }
}

// Pass in the value of the data attribute as `id`
// If the data has a previous/next property
// use its value to get the previous/next page, otherwise
// use the base endpoint
// Then create some HTML from the data and add it to
// the page, finally updating the disabled state of
// each button
async function fetchData(id) {
  const endpoint = data[id] || base;
  const res = await fetch(endpoint);
  data = await res.json();
  const html = createHTML(data.results);
  planets.innerHTML = html;
  previous.disabled = !data.previous ? true : false;
  next.disabled = !data.next ? true : false;
}

// Pass in the new data, `map` over it, and return
// a string of HTML
function createHTML(data) {
  return data
    .map(planet => {
      return `
        <section >
          <h4>${planet.name}</h4>
          <p>Population: ${planet.population}</p>
          <p>Terrain: ${planet.terrain}</p>
        </section>
      `;
    })
    .join('');
}
.planet { border: 1px solid #efefef; padding: 0.4em; }
.button:hover { cursor: pointer; }
<section >
  <button data-id="previous" >Prev</button>
  <button data-id="next" >Next</button>
</section>
<section ></section>

Additional documentation

  • Related