To reproduce, click on the red exit button, then on the 2nd button.
function onYouTubeIframeAPIReady() {
let playlists = Array(3);
playlists[1] = "0dgNc5S8cLI,mnfmQe8Mv1g,-Xgi_way56U,CHahce95B1g";
for (let i = 1; i <= 3; i ) {
let playvars = {}
if (playlists[i]) {
playvars.playerVars = {
playlist: playlists[i]
};
}
players.add(".playSingle" i, playvars);
}
players.add(".playSingle2", {
playerVars: {
listType: "playlist",
list: "PLYeOyMz9C9kYmnPHfw5-ItOxYBiMG4amq"
}
});
}
CodePudding user response:
Debugging Code
This question is a good example as to why learning how to debug your own code is critical to solving issues.
Let's start with what can be done to debug. OP provided two links (which are not minimal, reproducible examples)
- Working: https://jsfiddle.net/4x6e3am5/
- Not working: https://jsfiddle.net/2q7yknrv/1/
To debug I first took the two examples and did a simple text comparison (tools like DiffChecker are useful for this). This showed me what changed. And there were a couple of changes that stood out so the next thing I did was add some console.log()
lines to follow the code as it attempted to add a player. This revealed that the playerOptions
parameter being passed was empty, meaning the playlist information was never passed.
Upon digging further I noticed an important change. The one that does work changed this line in the for
loop:
players.add(".playSingle1" i, playvars);
to this:
players.add(".playSingle" i, playvars);
Why is this significant? Because in the first example there is an element on the page with the class playSingle1
. This means the first example will find the element and attempt to add a new player, which will fail (for reasons mentioned regarding the API documentation).
In the second example (which is working), it references an element with a class name of playSingle
, which does not exist. This means the attempt to add a player does nothing.
So why does the second example work? Because the broken code in the for
loop doesn't do anything, and because the code is executed sequentially, this means by the time the playSingle2
player is added, the code can run as intended.
Evidence
This can be verified a few different ways.
First, we can take the example that does not work and simply change the playSingle1
to playSingle
inside of the onYouTubeIframeAPIReady()
function. This fixes the error (for that specific video) for the reasons mentioned above.
A second way we can fix this is by removing or commenting out the for
loop code entirely and only leaving the playSingle2
code. This also fixes the issue (for that specific video).
Issues With Player API Playlist
Let's first look at the for
loop provided and step through it to understand what is wrong with it.
let playlists = Array(3);
playlists[1] = "0dgNc5S8cLI,mnfmQe8Mv1g,-Xgi_way56U,CHahce95B1g";
for (let i = 1; i <= 3; i ) {
let playvars = {}
if (playlists[i]) {
playvars.playerVars = {
playlist: playlists[i]
};
}
players.add(".playSingle" i, playvars);
}
First, it declares an array called playlists
with 3 empty/undefined values.
Next, it sets the second index (as arrays start at a 0 index) to a string that is comma separated.
This means the array actually looks like this when we start the loop:
[undefined, '0dgNc5S8cLI,mnfmQe8Mv1g,-Xgi_way56U,CHahce95B1g', undefined]
Then, this for
loop does 3 passes, each time taking an index from the playlists
array and storing a value in a variable, then passing this to the add()
method to add a player.
But, the issue is the array still has 2 empty/undefined values.
As specified by YouTube's official API for the IFrame Player, the playlist parameter should be:
This parameter specifies a comma-separated list of video IDs to play. If you specify a value, the first video that plays will be the VIDEO_ID specified in the URL path, and the videos specified in the playlist parameter will play thereafter.
This means to add a playlist you do not need a loop or array. You can only pass in a single string which contains a comma separated value of videos.
The alternative is a premade playlist existing on YouTube already, in which case you can use the list
and listType
parameters to load the playlist. You can not use both methods at the same time. OP was using both method and attempting to load them on to 2 separate players. This code executed every time the onYouTubeIframeAPIReady()
function ran, regardless of which player/video/playlist was actually being viewed. A suggestion would be to use some logic with a simple if/else
statement to determine which video/playlist is being viewed and only run the playlist code for that.
Code of Conduct
Stack Overflow is a question and answer site that is populated with volunteers. This means that when you have a question, you should be respectful of those trying to help. Many people here are taking time out of their day to provide help/knowledge/insight as well as solutions to problems.
If someone offers information that can help, do not harass or berate them. Almost always, that information was shared with the intention of helping solve the problem. If you need clarity, feel free to ask but remember users here are not paid and are helping when they have the availability to do so. Sometimes responses and answers can take time so always be patient.