I want it to behave in a way that everytime I clicked the thumbnails of those individual playlist, the upper main video changes to the newly clicked video.
Here is the javascript code I have.
// constants
const key = 'myAPI key here';
const playlistId = 'UUuSrv3qgQA7SSi6R9bWag5A';
var URL = 'https://www.googleapis.com/youtube/v3/playlistItems';
//youtube API sees all these info, so that it knows what kind of information you want to retrieve
const options = {
playlistId: playlistId,
maxResults: 20,
key: key,
part: 'snippet'
};
let loadMainVideo = function () {
//put in options into the URL so that youtube API will work
URL += '?' + Object.keys(options).map((k) => k + '=' + encodeURIComponent(options[k])).join('&');
//use fetch to get HTTP request
fetch(URL)
.then(res => res.json())
.then(function (data) {
// console.log(data);
loadPlayList(data);
var first_video_id = data.items[0].snippet.resourceId.videoId;
//put the 1st video in the playlist into the dom
document.getElementById('youtube_feed').innerHTML = `
<iframe width="1280" height="720" src="https://www.youtube.com/embed/${first_video_id}" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
`
})
.catch(err => console.log(err))
}
loadMainVideo();
/*
Load Playlist
*/
function loadPlayList(data) {
console.log(data.items.length); //this gives you 20 which is correct
//let's try loop through the array using for loop
for (let i = 1; i < data.items.length; i++) {
var thumbnail = data.items[i].snippet.thumbnails.medium.url;
var title = data.items[i].snippet.title.substring(0, 50);
var videoID = data.items[i].snippet.resourceId.videoId;
document.getElementById('youtube_playlist').innerHTML += `
<div class="individual_list_item" data-key = "${videoID}">
<img src="${thumbnail}" alt="video_thumbnail_placeholder" class="thumbnails">
<p class="playlist_titles">${title}</p>
</div>
`;
}
}
document.getElementById('youtube_playlist').addEventListener('click', function () {
//1. click thumbnail, log video ID of the thumbnail video.
//2. click thumbnail , insert video ID of the thumbnail video into first_video_id in fetch function.
})
In the snippet above I have already successfully inserted all the video snippet into the DOM using .innerHTML += ,
The event.target is the element that was clicked (fired the click event).
If an element has a data attribute on it, it will have a dataset property.
event.target.dataset.key
You can think of is as, dataset.key === data-key
// Var for storing the id/key
let key;
// If the element that was clicked has a dataset.key
if (event.target.dataset.key) {
// Store the key
key = event.target.dataset.key;
// If it does not have a dataset.key, it must be one of the childern, either the img, or p element
} else {
// Go up to the parrent element and get the id/key
key = event.target.parentElement.dataset.key;
}
okay… right now I have been able to log out individual video’s video_id whenever I click on the thumbnail.
let loadMainVideo = function () {
//put in options into the URL so that youtube API will work
URL += '?' + Object.keys(options).map((k) => k + '=' + encodeURIComponent(options[k])).join('&');
//use fetch to get HTTP request
fetch(URL)
.then(res => res.json())
.then(function (data) {
loadPlayList(data);
var first_video_id = data.items[0].snippet.resourceId.videoId;
//put the 1st video in the playlist into the dom
document.getElementById('youtube_feed').innerHTML = `
<iframe width="1280" height="720" src="https://www.youtube.com/embed/${first_video_id}" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
`
document
.getElementById('youtube_playlist')
.addEventListener('click', function (event) {
// const target = event.target;
// console.log({ target });
if (event.target.dataset.key) {
console.log(event.target.dataset.key);
first_video_id = event.target.dataset.key;
} else {
console.log(event.target.parentElement.dataset.key);
first_video_id = event.target.parentElement.dataset.key;
}
// console.log("The key is", target);
});
})
.catch(err => console.log(err))
}
loadMainVideo();
but how do I pass it into this part of the function?
var first_video_id = data.items[0].snippet.resourceId.videoId;
//put the 1st video in the playlist into the dom
document.getElementById('youtube_feed').innerHTML = `
<iframe width="1280" height="720" src="https://www.youtube.com/embed/${first_video_id}" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
`
my aim is that every time I click on the thumbnail the main video feed switch to the co-responding video.
I would suggest you separate the logic out into functions and maybe an object to store data.
As far as I can tell you would need a fetch function, 2 render functions and a callback handler function (make it a named function and pass it to the click event handler). The callback can set the id in an object or you can call the main video render function from within it and pass it the id.
function fetchPlaylist()
function renderPlaylist(data)
function renderMainVideo(id)
function handleGetPlaylistVideo()
Do you have your code anywhere we can see it in a more complete state.
Here is my progress so far, I am at the last step where I need to created the call back function whenever user click on those playlist items. Logic wise I am stuck.
To put it in pseudocode I think it is something like this:
whenever the user click the specific video, 1st get the videoID of that video, 2nd, pass in that videoID into mainVideoID.
But I couldn’t convert this into javascript. Here is my code.
/*
TODO list
1. need a fetch function to handle HTTP request
2. renderMainVideo()
3. renderPlaylist()
4. call back function for the click event
*/
/*
Global variables and constants
*/
const key = 'my api key';
const playlistId = 'UUuSrv3qgQA7SSi6R9bWag5A';
var URL = 'https://www.googleapis.com/youtube/v3/playlistItems';
const options = {
playlistId: playlistId,
maxResults: 20,
key: key,
part: 'snippet'
};
var mainVideoID;
var new_data;
/*
HTTP request
*/
URL += '?' + Object.keys(options).map((k) => k + '=' + encodeURIComponent(options[k])).join('&');
fetch(URL)
.then(res => res.json())
.then(function (data) {
new_data = data;
mainVideoID = data.items[0].snippet.resourceId.videoId;
console.log(data);
renderPlaylist(data);
})
/*
Render main video
*/
setTimeout(function renderMainVideo() {
document.getElementById('youtube_feed').innerHTML = `
<iframe width="1280" height="720" src="https://www.youtube.com/embed/${mainVideoID}" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>`
}, 1000);
/*
Render Playlist
*/
function renderPlaylist(data) {
console.log(data.items.length); //this gives you 20 which is correct
//let's try loop through the array using for loop
for (let i = 1; i < data.items.length; i++) {
var thumbnail = data.items[i].snippet.thumbnails.medium.url;
var title = data.items[i].snippet.title.substring(0, 50);
var videoID = data.items[i].snippet.resourceId.videoId;
document.getElementById('youtube_playlist').innerHTML += `
<div class="individual_list_item" data-key = "${videoID}">
<img src="${thumbnail}" alt="video_thumbnail_placeholder" class="thumbnails">
<p class="playlist_titles">${title}</p>
</div>
`;
}
}
/*
Call back function for the click event
*/
/* every time you click the video, you want to get the videoID of that specific video */
// setTimeout(function () {
// console.log("main video ID is:" + mainVideoID);
// }, 1000);
function setID() {
mainVideoID =
}
First unwrap the renderMainVideo definition from the setTimeout. If you want to call renderMain in a setTimeout just pass it in as a callback. Now use the code i posted before and instead of just saving the id, call renderMainVideo and pass in the id.
Here is a pen where i use the data-key as the size for the placeholder image, i think it should give you an idea. I set a default parameter value of 250 on the first run of renderMainVideo (when setTimeout calls it on page load), then when you click the thumbnail or title it sets the key to the data-key value (450) and calls renderMainVideo passing in the key as an argument.
If I take renderMainVideo out of the setTimeout function, the main video will not be rendered.
Click handler works just fine.
var mainVideoID;
var new_data;
/*
HTTP request
*/
URL += '?' + Object.keys(options).map((k) => k + '=' + encodeURIComponent(options[k])).join('&');
fetch(URL)
.then(res => res.json())
.then(function (data) {
new_data = data;
mainVideoID = data.items[0].snippet.resourceId.videoId;
console.log(data);
renderPlaylist(data);
})
/*
Render main video
*/
function renderMainVideo(mainVideoID) {
document.getElementById('youtube_feed').innerHTML = `
<iframe width="1280" height="720" src="https://www.youtube.com/embed/${mainVideoID}" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>`
}
/*
Render Playlist
*/
function renderPlaylist(data) {
console.log(data.items.length); //this gives you 20 which is correct
//let's try loop through the array using for loop
for (let i = 1; i < data.items.length; i++) {
var thumbnail = data.items[i].snippet.thumbnails.medium.url;
var title = data.items[i].snippet.title.substring(0, 50);
var videoID = data.items[i].snippet.resourceId.videoId;
document.getElementById('youtube_playlist').innerHTML += `
<div class="individual_list_item" data-key = "${videoID}">
<img src="${thumbnail}" alt="video_thumbnail_placeholder" class="thumbnails">
<p class="playlist_titles">${title}</p>
</div>
`;
}
}
/*
Call back function for the click event
*/
/* every time you click the video, you want to get the videoID of that specific video */
document.getElementById('youtube_playlist')
.addEventListener('click', function (event) {
const target = event.target;
let mainVideoID;
if (event.target.dataset.key) {
mainVideoID = event.target.dataset.key;
renderMainVideo(mainVideoID);
} else {
mainVideoID = event.target.parentElement.dataset.key;
renderMainVideo(mainVideoID);
}
})
setTimeout(renderMainVideo, 1000);
yeah It is the issue.
I couldn’t get it to print out output inside the renderMainVideo function, but that’s why the 1st time I showed you the code I put it inside the setTimeout function.
I would really suggest you make an actual fetch function and store the results in an object before you try to reference the data from the fetch operation. Or make the fetch function return the data (or a promise) and then grab it where you need it. The fetch function should only do that and nothing else.