Home > Blockchain >  My data from my api won't display in my html (im still new to coding but here is my code)
My data from my api won't display in my html (im still new to coding but here is my code)

Time:04-07

var listApi = document.querySelector(".list-item")
var searchApi = document.getElementById("search-api")
document.querySelector("#enter").addEventListener("click", e => {
    e.preventDefault();
    var inputValue = searchApi.value; 
    fetch('https://wft-geo-db.p.rapidapi.com/v1/geo/cities/'      inputValue, options)
    .then(response => response.json())
    .then(response => console.log(response))
    .then((data) => {
        var title = document.createElement("li")
        title.setAttribute = ".list-item";
        title.innerText = data;
    })
    .catch(err => console.error(err));

});

//Html portion

<h2 >Results</h2>
<ul id="result-list">
  <li ></li>

</ul>

The api works fine as it displays the data in the console, i just can figure how to get it in my html.

CodePudding user response:

The only missing part is how you loop over your data and add items to your list, so here's a quick example.

// Cache the list element
const ul = document.querySelector('ul');

// Your data will look something like this
// where `data` is an object with a property
// with an array
const data = {
  cities: [
    { name: 'London' },
    { name: 'Paris' }    
  ]
};

// Once your data has returned, loop
// over the array, and then add each new item
// to the list
for (const city of data.cities) {
  const item = document.createElement('li');
  item.textContent = city.name;
  ul.appendChild(item);
}
<ul></ul>

If you wanted another approach that uses more "modern" methods:

// Cache the list element
const ul = document.querySelector('ul');

// Your data will look something like this
// where `data` is an object with a property
// with an array
const data = {
  cities: [
    { name: 'London' },
    { name: 'Paris' }    
  ]
};

// Create an array of HTML strings by mapping
// over the data
const html = data.cities.map(city => {
  return `<li>${city.name}</li>`;
}).join('');

// And then adding that joined string to the list
ul.insertAdjacentHTML('beforeend', html);
<ul></ul>

Addition information

CodePudding user response:

When you create an element with document.createElement it exists only in memory-- it isn't actually attached to the DOM yet. You need to insert it somewhere, like so:

var listApi = document.querySelector(".list-item")
var searchApi = document.getElementById("search-api")
document.querySelector("#enter").addEventListener("click", e => {
    e.preventDefault();
    var inputValue = searchApi.value; 
    fetch('https://wft-geo-db.p.rapidapi.com/v1/geo/cities/'      inputValue, options)
    .then(response => response.json())
    .then(response => console.log(response))
    .then((data) => {
        var title = document.createElement("li")
        title.setAttribute = ".list-item"
        title.innerText = data;
        var list = document.getElementById("result-list");
        list.appendChild(title);
    })
    .catch(err => console.error(err));

});

Also note your line title.setAttribute = ".list-item" won't work as you expect-- you are overwriting the setAttribute function with a string. Better to just use classList as title.classList.add('list-item');

Also, as user Andy points out in the comments, you have another problem with your chaining of .thens-- specifically, you have a .then() that console.logs the result and returns nothing. The way promise chains work is that the next .then will act on the result passed from the previous .then; however, .then(response => console.log(response)) will return undefined, so the data argument coming into your next .then will be undefined. Below is a code example that fixes both the setAttribute issue and the .then issue:

var listApi = document.querySelector(".list-item")
var searchApi = document.getElementById("search-api")
document.querySelector("#enter").addEventListener("click", e => {
    e.preventDefault();
    var inputValue = searchApi.value; 
    fetch('https://wft-geo-db.p.rapidapi.com/v1/geo/cities/'      inputValue, options)
    .then(response => response.json())
    .then(response => {
        console.log(response);
        return response;
    })
    .then((data) => {
        var title = document.createElement("li")
        title.classList.add("list-item");
        title.innerText = data;
        var list = document.getElementById("result-list");
        list.appendChild(title);
    })
    .catch(err => console.error(err));

});

Finally, if you are just attempting to insert a plain object or array as text into the DOM you will likely get unexpected results, such as it displaying simply as "object Object" in the <li>. Let's presume for a moment that your response looks something like this:

{
    data: ['MacReady', 'Childs', 'Blair', 'Nauls', 'Clark', 'Palmer']
}

To write this data to the DOM, you'd need to access it at the data property, then map over it (either with a loop or using an array method like .forEach) and add each item to an element (like an <li> in your case) and insert it to the DOM. Here's an example:

var listApi = document.querySelector(".list-item")
var searchApi = document.getElementById("search-api")
document.querySelector("#enter").addEventListener("click", e => {
    e.preventDefault();
    var inputValue = searchApi.value; 
    fetch('https://wft-geo-db.p.rapidapi.com/v1/geo/cities/'      inputValue, options)
    .then(response => response.json())
    .then(response => {
        console.log(response);
        return response;
    })
    .then((data) => {
        let myList = data.data;

        myList.forEach(datum => {
            var title = document.createElement("li")
            title.classList.add("list-item");
            title.innerText = datum;
            var list = document.getElementById("result-list");
            list.appendChild(title);
        });
    })
    .catch(err => console.error(err));

});

There are other approaches to this-- using a for loop, or using DOM fragments to increase performance, but something along these lines should work for your use case.

CodePudding user response:

You need to update an element that is in the dom.

var listApi = document.querySelector(".list-item")
var searchApi = document.getElementById("search-api")
document.querySelector("#enter").addEventListener("click", e => {
    e.preventDefault();
    var inputValue = searchApi.value; 
    fetch('https://wft-geo-db.p.rapidapi.com/v1/geo/cities/'      inputValue, options)
    .then(response => response.json())
    .then(response => console.log(response))
    .then((data) => {
        listApi.innerText = data;
    })
    .catch(err => console.error(err));

});
  • Related