Converting 'For Loop' to 'forEach' and vice versa

This:

    function hideAllButtons(button) {
      button.querySelectorAll(".play, .pause, .speaker").forEach(hide);
    }

Is changed to this:

      function hideAllButtons(button) {
        const buttons = button.querySelectorAll(".play, .pause, .speaker");
        for (let i = 0; i < buttons.length; i += 1) {
          hide(buttons[i]);
        }
      }

How would I add For Loop to this code?

      function hideAllButtons(button) {
        const buttonSelectors = ".play, .pause, .speaker";
        button.querySelectorAll(buttonSelectors).forEach(hide);
      }

I don’t understand what you’re asking, you’ve added the for loop, I can see it in the second snippet??

I’m trying to add ‘for loop’ to this code:
It’s not in here.
This one is set up differently.

      function hideAllButtons(button) {
        const buttonSelectors = ".play, .pause, .speaker";
        button.querySelectorAll(buttonSelectors).forEach(hide);
      }
function hideAllButtons(button) {
  const buttons = button.querySelectorAll(".play, .pause, .speaker");
  for (let i = 0; i < buttons.length; i += 1) {
    hide(buttons[i]);
  }
}

It’s here, it makes no difference if you save that string as a variable and use the variable or if you pass the string in directly, it’s exactly the same. It’s not set up differently, it’s identical.

Where would this piece go?
(buttonSelectors)
https://jsfiddle.net/pezuLqvo/95/

I get up this far, then I’m stuck:

function hideAllButtons(button) {
  const buttonSelectors = ".play, .pause, .speaker";
  for (let i = 0; i < buttons.length; i += 1) {
    hide(buttons[i]);
  }
}
      function hideAllButtons(button) {
        const buttonSelectors = ".play, .pause, .speaker";
        button.querySelectorAll(buttonSelectors).forEach(hide);
      }

I don’t know how to phrase this better, or to explain this further: you’ve literally written the code.

This

const buttonSelectors = ".play, .pause, .speaker";
const buttons = button.querySelectorAll(buttonSelectors);

Is literally the same as

const buttons = button.querySelectorAll(".play, .pause, .speaker");

I think if you are having issues here you need to look go back to the very, very basics of JavaScript - ie how do you declare a variable, what is a variable, what is a string.

Edit:

This doesn’t work:

function hideAllButtons(button) {
  const buttonSelectors = ".play, .pause, .speaker";
  for (let i = 0; i < buttons.length; i += 1) {
    hide(buttons[i]);
  }
}

Because you’ve taken the perfectly fine working solution you had and deleted the part that made it work (buttons, the collection of buttons from the querySelectorAll call, is no longer there, you’ve removed it)

I don’t get you.

function hideAllButtons(button) {
    const buttons = button.querySelectorAll(".play, .pause, .speaker");
    for (let i = 0; i < buttons.length; i += 1) {
      hide(buttons[i])
    }
  }

This is your code from the jsfiddle. It’s already working and utilizes the for loop you keep asking about, so what’s the problem?

This:

      function hideAllButtons(button) {
        const buttonSelectors = ".play, .pause, .speaker";
        button.querySelectorAll(buttonSelectors).forEach(hide);
      }

Would become this:

It would’ve been changed to this, I just got it:
https://jsfiddle.net/pezuLqvo/131/

  function hideAllButtons(button) {
    const buttonSelectors = ".play, .pause, .speaker";
    const buttons = button.querySelectorAll(buttonSelectors);
    for (let i = 0; i < buttons.length; i += 1) {
      hide(buttons[i]);
    }
  }

How would I convert this code to forEach?
https://jsfiddle.net/d72Lp43v/375/

    function onPlayerStateChange(event) {
        if (event.data == YT.PlayerState.PLAYING) {
            const temp = event.target.a.src;
            for (let i = 0; i < players.length; i++) {
                if (players[i].a.src != temp) players[i].pauseVideo();
            }
        }
    }

I think I got the 1st part here:
https://jsfiddle.net/d72Lp43v/377/

function onPlayerStateChange(event) {
    if (event.data === YT.PlayerState.PLAYING) {
      const temp = event.target.a.src;
      players.forEach(function pauseOtherVideos(player) {
        if (player.a.src !== temp) {
          player.pauseVideo();
        }
      });
    }
  }

Next would be putting it inside this:

 function onPlayerStateChange(event) {
    if (event.data === YT.PlayerState.PLAYING) {
      const otherVideos = (player) => player !== event.target;
      const pauseVideo = (player) => player.pauseVideo();
      players.filter(otherVideos).forEach(pauseVideo);
    }
  }

It would become this I think
https://jsfiddle.net/d72Lp43v/386/

  function onPlayerStateChange(event) {
    if (event.data === YT.PlayerState.PLAYING) {
      const temp = event.target.a.src;
      const otherVideos = (player) => player.a.src !== temp;
      const pauseVideo = (player) => player.pauseVideo();
      players.filter(otherVideos).forEach(pauseVideo);
    }
  }

Can make it even shorter:

function onPlayerStateChange(event) {
  if (event.data == YT.PlayerState.PLAYING) {
    const temp = event.target.a.src;
    players.forEach( (player) => temp !== player.a.src ? player.pauseVideo() : `` )
    }
}

or

function onPlayerStateChange(event) {
  if (event.data == YT.PlayerState.PLAYING) {
    players.forEach( (player) => event.target.a.src !== player.a.src ? player.pauseVideo() : `` )
  }
}
1 Like

How would I fix this line
https://jsfiddle.net/d72Lp43v/396/

It’s this line here:
const otherVideos = (video) => video !== player.a.src !== temp;
Which I’m having issues with.

 function onPlayerStateChange(event) {
    const player = event.target;
    if (event.data === YT.PlayerState.PLAYING) {
      const temp = event.target.a.src;
      const otherVideos = (video) => video !== player.a.src !== temp;
      const pauseVideo = (video) => video.pauseVideo();
      players.filter(otherVideos).forEach(pauseVideo);
    }

    const playerVars = player.b.b.playerVars;
    if (playerVars.loop && event.data === YT.PlayerState.ENDED) {
      player.seekTo(playerVars.start);
    }
  }

You’re comparing video against !== player.a.src and !== temp in the same expression, can’t do that. Each “test” must be separated.

const otherVideos = (video) => video !== player.a.src || video !== temp;
This translates to "if video is not player.a.src or temp

I’ve used || which means OR, if you need them both to evaluate to true/false, use && instead.

I tried adding your suggestions into the 2nd code and it didn’t work.

This Works:
https://jsfiddle.net/d72Lp43v/418/

  function onPlayerStateChange(event) {
    if (event.data === YT.PlayerState.PLAYING) {
      const temp = event.target.getVideoUrl();
      const otherVideos = (player) => player.getVideoUrl() !== temp;
      const pauseVideo = (player) => player.pauseVideo();
      players.filter(otherVideos).forEach(pauseVideo);
    }
    const player = event.target;
    const playerVars = player.b.b.playerVars;
    if (playerVars.loop && event.data === YT.PlayerState.ENDED) {
      player.seekTo(playerVars.start);
    }
  }

And this simplified code doesn’t, how come?
https://jsfiddle.net/d72Lp43v/421/

  function onPlayerStateChange(event) {
    const player = event.target;
    if (event.data === YT.PlayerState.PLAYING) {
      const temp = event.target.getVideoUrl();
      const otherVideos = (video) => video !== player.getVideoUrl() !== temp;
      const pauseVideo = (video) => video.pauseVideo();
      players.filter(otherVideos).forEach(pauseVideo);
    }

    const playerVars = player.b.b.playerVars;
    if (playerVars.loop && event.data === YT.PlayerState.ENDED) {
      player.seekTo(playerVars.start);
    }
  }