0

i am trying to make a simple list where each item is going to show after another

html

<!DOCTYPE html>
<html>
<head>

</head>
<body>
    <script src = "async.js"></script>
</body>
</html>

javaScript

let list = [
    {
        name: 'one',
    },
    {
        name: 'two',
    }
]
let output = '';
function print(){
    setTimeout(()=>{
        list.forEach(function(element){
            output = `<li>${element.name}</li>`; // critical line
            document.body.innerHTML += output;
        })
    },500)
}

function add(element){
   setTimeout(() =>{
    list.push(element);
   },400)
}

add({name: 'three'});

let c=0;
setTimeout(()=>{  // waits for add function to be executed
    for(let i=0;i<list.length;i++){
        setTimeout(print,c);
        c+=1000;
    }
},1000)

The problem is that output value gets all of names every iteration and prints 3 names 3 times instead of printing 1 name at the time. Can you explain this?

2
  • You pass the whole list to print 3 times, so it prints the whole list 3 times. Not that surprising. :-) Commented Mar 27, 2020 at 22:06
  • So close yet so far :D Commented Mar 27, 2020 at 22:42

1 Answer 1

3
  1. The list starts with two items.
  2. add({name: 'three'}); adds a third
  3. for(let i=0;i<list.length;i++){ loops over the list and calls setTimeout(print,c); three times (because there are three things in the list)
  4. function print(){ prints each of the the three things in the list (and it runs three times because of step 3).

So… if I understand your misunderstanding correctly:

print prints every item in the list, because it loops over the list.

print doesn't print a specific item because it (a) isn't designed to print one item and (b) You haven't passed it an argument that would tell it which item to print anyway.

Possibly you want something along the lines of:

let list = [{
    name: 'one',
  },
  {
    name: 'two',
  },
  {
    name: 'three'
  }
];

let current_index = 0;

function print() {
  const element = list[current_index];
  if (!element) {
    return; // end of the list
  }
  const output = `<li>${element.name}</li>`;
  document.querySelector("ul").innerHTML += output;
  current_index++;
  setTimeout(print, 1000);
}

setTimeout(print, 1000);
<ul></ul>

… where you keep track of which element in the array you are dealing with, and increment the counter as you add the data to the HTML and not all in one immediate loop.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for such detailed answer, it was more than helpful !

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.