Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript: for loop to retrieve and print a certain amount of API data

I have recently started playing around with Javascript and API arrays, in order to try to understand how to retrieve and work with different APIs.

The question of Javascript loops and arrays has been asked and answered several times, both here in StackOverflow and other websites.

However, I seem to be unable to find (Potentially due to my lack of understanding and/or keywords used) exactly what I am looking for.

My current project is to create a WebApp that retrieves information from an API (I chose the random user API) and display this information on the screen.

Implementation and Issue

So far I have been focusing on retrieving specific data from the API (which I have succeeded to do, to a certain degree) and displaying them on a browser. I decided that I wanted to show several users at the same time, limiting it to 15 users shown at a time (when the browser is refreshed it should show another 15 users randomly (part of the API)).

Although I am aware that I can directly request multiple users, by using the results parameter, I am trying to do this myself via loops so that I can understand how to retrieve multiple information and display them as lists.

Implementation

  • The HTML file: very basic, it contains a main div and inside the div an unordered list element, also containing an element. I will need to remove certain elements from the HTML file and have the JS file create them via innerHTML method as I move forward.

  • CSS file: very basic for now, focusing on the JS file.

  • The Javascript file: pretty basic for now too. It contains a constant variable with the fetched API URL. It retrieves the data as JSON and then adds specific information (in this case first name and photo) in their specified IDs, using document.getElementById().

I have researched methods to retrieving and displaying information from APIs and so far have obtained a basic understanding. However, I seem to have come to a halt (because I do not fully understand how to use for-loops or map() to go through my current JS code and display the same data N amount of times for N amount of users).

Issue

Before adding the for-loop, the js file retrieves the required information of one random user, which is what I would expect it to do. However, once my for-loop has been added, it stops displaying anything, and does not provide any error messages that could help me solve the issue.

I did try the following for-loop to see if I had at least understood the very basics and printed the results in the console:

for ( var i = 0; i < 15 ; i++) {
    console.log(i)
}

I have attached the block of code snippets to a JSbin link. There, you can see the current state and issue.

Current HTML + JS files and output (JS Bin): In this example I have commented out the for-loop to show that it does work up to a certain point.

const testapi = fetch("https://randomuser.me/api/?gender=male");


/*for ( var i = 0; i < testapi.length ; i++) {*/
testapi
.then(data => data.json())
.then(data => document.getElementById('test').innerHTML = "<h1>" + data.results[0].gender + "</h1>" + "<p>" + data.results[0].name.first + "</p>" + document.getElementById("myImg").setAttribute('src',data.results[0].picture.medium))

.catch(function(err) {
    console.log('Fetch Error :-S', err);
  });

/*}*/
li {
  display:flex;
  flex-direction: column;
  align-items:center;
  box-shadow: 2px 4px 25px rgba(0, 0, 0, .1);
}
<!DOCTYPE html>
<html lang="eng">
  <head>
    <meta charset="utf-8">
    <link rel="stylesheet" type="text/css" href="style.css">
  </head>
  <body>
    <div>
      <ul>
        <li>
          <div id="test"></div>
          <img src="" id="myImg" />
        </li>
      </ul>
    </div>
    <script src="script.js"></script>
  </body>
</html>

Visited Websites

  • Loop through and pull in a certain amount of data
  • Javascript for loop not looping through array
  • JavaScript Loops
  • Write JavaScript loops using map, filter, reduce and find
like image 339
Xertiem Avatar asked Feb 27 '19 12:02

Xertiem


1 Answers

Have a go at this - I call the function again in the resolve if there are more URLs to fetch:

See example 2 how to use template literals

let cnt = 0;
const maxNum = 3;

function getEm() {
  if (cnt >= maxNum) return; // stop

  fetch("https://randomuser.me/api/?gender=male")
    .then(data => data.json())
    .then(data => {
      document.getElementById('test').innerHTML += '<li>'+
      "<h1>" + data.results[0].gender + "</h1>" + 
      "<p>" + data.results[0].name.first + "</p>" + 
      '<img src="'+data.results[0].picture.medium+'"/>'+
      '</li>';

     // here is the magic

      cnt++; 
      getEm()

    })
    .catch(function(err) {
      console.log('Fetch Error :-S', err);
    });
}
getEm()
li {
  display: flex;
  flex-direction: column;
  align-items: center;
  box-shadow: 2px 4px 25px rgba(0, 0, 0, .1);
}
<!DOCTYPE html>
<html lang="eng">

<head>
  <meta charset="utf-8">
  <link rel="stylesheet" type="text/css" href="style.css">
</head>

<body>
  <div>
    <ul id="test">
    </ul>
  </div>
  <script src="script.js"></script>
</body>

</html>

Multiple users in one go using template literals:

let users = []
fetch("https://randomuser.me/api/?results=15")
  .then(data => data.json())
  .then(data => {
    for (user of data.results) {
      users.push(
        `<li>
          <h1>${user.gender}</h1>
          <p>${user.name.first}</p>
          <img src="${user.picture.medium}"/>
        </li>`);
    }
    document.getElementById('test').innerHTML= users.join("");
  })
li {
  display: flex;
  flex-direction: column;
  align-items: center;
  box-shadow: 2px 4px 25px rgba(0, 0, 0, .1);
}
<div>
  <ul id="test"></ul>
</div>
like image 60
mplungjan Avatar answered Nov 18 '22 11:11

mplungjan