loading...

Practical Explanation Of Javascript Iterators(with a demo app)

bjhaid_93 profile image /[Abejide Femi Jr]\s/ Updated on ・4 min read

What are Iterators?

Iterators in a layman term are used to iterate through a collection of objects.Iterators is an ES6(EcmaScript6) feature and it is an advanced loops that can be paused, an iterator provides the next() method which returns the next item in the sequence, the value property can be used to access value of the current item, an iterator is considered to be terminated when the next() method return an object with the done property set to be true.
Here is an Example Below

     function Iterator(names){
        //set the index to 0
        let nextIndex = 0;
        return {
            next() {
            return nextIndex < names.length 
                    ?
                {value:names[nextIndex++], done:false}
                    : 
                {done:true}
            }
        }
    }
    //Create an array
    let names = ['wale', 'ali', 'john', 'bubu'];
    //pass the array into the Iterator function
    let name = Iterator(names);
    console.log(name.next().value);//wale
    console.log(name.next().value);//ali
    console.log(name.next().value);//john
    console.log(name.next().value);//bubu
    console.log(name.next().value);//undefined

From the code above, the first four calls gives us the value of the first four item in the array, the last returns undefined, because the iteration was terminated as there is no longer item in the array to iterate through.
Below is the console output
output

I will be explaining iterators practically by building a demo app, so it gives us an overview of what iterators is being used for in a real-world application, In this app, i will be fetching data from https://api.github.com/users, it will enable us to view the first 46 users profile.
Here is the HTML structure

    <!doctype html>
<html lang="en">
  <head>
    <title>Profile Scroller</title>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" integrity="sha384-PsH8R72JQ3SOdhVi3uxftmaW6Vc51MKb0q5P2rRUpPvrszuE4W1povHYgTpBfshb" crossorigin="anonymous">
  </head>
  <body>
    <div class="container">
      <div class="row">
        <div class="col-md-6 mx-auto text-center">
          <h1 class="mb-3">Profile Scroller</h1>
          <div id="imageDisplay"></div>
          <br>
          <div id="profileDisplay"></div>
          <br>
          <button id="next" class="btn btn-dark btn-block">Next</button>
        </div>
      </div>
    </div>

    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js" integrity="sha384-vFJXuSJphROIrBnz7yo7oB41mKfc8JzQZiCq4NCceLEaO4IHwicKwpJf9c9IpFgh" crossorigin="anonymous"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js" integrity="sha384-alpBpkh1PFOepccYVYDB4do5UnbKysX5WZXm3XxPqe5iKTfUKjNkCk9SaVuEZflJ" crossorigin="anonymous"></script>
    <script src="app.js"></script>
  </body>
</html>

Below is the Javascript code

         //create the function
  function Iterator(profile) {
    //set the index to 0
    let nextIndex = 0;

    return {
      next() {
        return nextIndex < profile.length 
              ?
          {value: profile[nextIndex++], done: false}
              :
          {done: true}
      }
    }
  }
  //html classes and ids stored in object
  let selector = {
    next : 'next',
    profile : 'profileDisplay',
    image: 'imageDisplay'
  }

//Using AJAX to fetch data
  var xhr = new XMLHttpRequest();

  xhr.open('GET', 'https://api.github.com/users', true);

  xhr.onload = function() {
    if (this.status === 200) {
      let data = JSON.parse(this.responseText);
      //pass the data coming in from the API into the iterator function
      let profile = Iterator(data);
      //call the load function to load the first profile
      loadProfile();
      //create an event listener for the button
      document.getElementById(selector.next).addEventListener('click', loadProfile);

      function loadProfile() {
        //get the value of the current and next data
        const currentProfile = profile.next().value
          //check if the current value is not undefined
          if(currentProfile !== undefined){
            document.getElementById(selector.profile).innerHTML =
            `<ul class="list-group">
                    <li class="list-group-item">Login: ${currentProfile.login}</li>
                    <li class="list-group-item">Id: ${currentProfile.id}</li>
                    <li class="list-group-item">Type: ${currentProfile.type}</li>
              </ul>
            `
            document.getElementById(selector.image).innerHTML = `<img src="${currentProfile.avatar_url}" class="w-25">`;
          }
        else {
          //reload the page after the last iteration
          window.location.reload();
        }
      }
    }
  }
  xhr.send()

In the code above, the Iterator Function was created, the data fetched from the API, was passed into the Iterator function, from the API we can access the avatar, login, id and type which is being displayed in the browser, after the last iteration, the page reloads, and the function loadProfile is called again.

Below is the output in the browser
output

Note

We also have Generators, but Generators are slightly different from iterators, The data being fetched can be created, also data can come from any External API.
Here is a link to the app
Thank You For Reading, Happy Coding!

Posted on May 29 '18 by:

Discussion

markdown guide
 

I like your real demo, but I think this article failed to mention an important point.

Iterators are supposed to be used in conjunction with iterables.

In your example

// Create an array
let names = ['wale', 'ali', 'john', 'bubu'];
 // pass the array into the Iterator function
let name = Iterator(names);

I understand that you want to show how iterators work, but iterators are not functions.
You can even use the name array directly since it is an iterable.

// Create an array
let names = ['wale', 'ali', 'john', 'bubu'];
let name = names[Symbol.iterator]();

name.next(); // {value: "wale", done: false}
name.next(); // {value: "ali", done: false}

I wrote an in depth article on this very topic, please check it out.