DEV Community

/[Abejide Femi Jr]\s/
/[Abejide Femi Jr]\s/

Posted on • Edited on

Practical Explanation Of Javascript Iterators(with a demo app)

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
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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()
Enter fullscreen mode Exit fullscreen mode

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!

Top comments (4)

Collapse
 
kepta profile image
Kushan Joshi • Edited

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.

Collapse
 
tmaxnoda profile image
Adeogun tobi

Nice tutorial bro

Collapse
 
bjhaid_93 profile image
/[Abejide Femi Jr]\s/

Thank you!

Collapse
 
shreelimbkar profile image
Shrivardhan Limbkar

simple and easy way to explain.