Liking and disliking posts, images, and more is a common feature in many modern apps. This tutorial shows you one way to do this with JavaScript in your frontend code. We'll use the Faker API to simulate real data in our contacts app and grab the selected contact data when we like or unlike the contact card. This pulls together several concepts from my 8 hour Vanilla JavaScript tutorial found here: ruclips.net/video/EfAl9bwzVZk/видео.html
Very cool video as usual, the way you structure your code keeps amazes me, may be set the cursor: pointer; on the like button (see, I'm smart 🤓) since I have nothing more to add, I just wanted to mention that adding a lot of event listeners may reduce the performance to a certain degree (not in this project), so alternatively we can add one event listener on the container and from within we can check event.target for the actual element we're looking for like this: main.addEventListener('click', event =>{ // Check if clicked element is a like button by looking into its class list if(event.target.classList.contains('like')){ // the same logic for the like click handler goes here } }); the down side is this handler will be triggered on wherever you click on the container element but still makes the app lighter. Thank you Dave for keeping our brains working 🤯
Once again, great feedback Ahmad. Thanks! Yes, a vast amount of event listeners could cause an issue. In such a case, your alternative looks like it would be a good solution! 🚀
@@DaveGrayTeachesCode Thanks Dave, Edit: I forgot to mention another benefit of adding the listener on the container is that we eliminate the need to re-adding the listeners when loading a new set of the elements (like in load more/pagination cases)
@@CynthiaSotoCaballerolYEAHl I've been using this technique for a long time ago and just now I know that it has a name "Event Delegation" 🤦♂️ anyway, if anyone is interested in this topic this link might be useful: www.sitepoint.com/javascript-event-delegation-is-easier-than-you-think/ Thanks for mentioning that
Hi Beth, it has been so long ago I cannot remember. I had it for a few years prior before making this tutorial almost a year ago. You can Google for free resources. Sorry I'm not more help on this one!
Thank you for this great tutorial. I would like to add the SVG icon on the top right of a table. However, it always shows outside. After a bit of research, it seems like tables and divs do not play well together. Any idea on how I can get around this?
You're welcome! There is no issue with using a div or divs with a table element. I think you will learn how to do this by learning about CSS position: ruclips.net/video/zqg4A6g9GfA/видео.html
Good question! Everything is contained inside of a function definition. The definitions are read before a function is called. If I called the function in the global scope, it would be a problem. A detailed look at scope here: ruclips.net/video/_E96W6ivHng/видео.html
@@DaveGrayTeachesCode Sorry for asking too many questions. If I understand correctly, at first the variables are hoisted to the top. So elemObj and const createCardElement are both hoisted to the top. Now createCardElement is read, its going to assign elemObj to createCardElements()?
@@streamx2 Notice initApp() is defined before the listener that calls it. No functions are called in the global scope. initApp() is called by the event listener. All function definitions are read as the script is processed. All functions are then only called within other functions. In that regard, they are not called before their definitions. Arrow functions do not get hoisted. Hoisting does not apply to const. (updated this after a quick review!)
I was looking for favorite image function as I had already done api fetching etc, posting the image with author and title, but then i saw how this code looks like and now I feel miserable by looking at mine, cuz it is just not this clean as i didnt even know i can render api data like this and all... To even use the favorite function id have to probably rewrite my whole code. ouch. Anyway ill probably now watch the whole tutorial of 8h when i have time, just to get to know how to use everything better...
@@DaveGrayTeachesCode i should say thank you instead, the way you show to render fetched data is what I definitely need to learn, would make it way easier to work with this all for me
Ah hello again, Since ive been doing image scroller and the fav function has been kicking me a lot where it hurts, can someone tell me why, i get "custom.js:16 Uncaught TypeError: Cannot read property 'toggle' of undefined at myFunctionFavo (custom.js:16) at HTMLButtonElement.onclick (index.html:31) myFunctionFavo @ custom.js:16 onclick @ index.html:31" code parts below-------- html: 21. Favorite js: function myFunctionFavo() { var x = document.getElementsByClassName('image__favorite fav_button'); if (x.innerHTML === "Favorite") { x.innerHTML = "Favorited"; x.classList.toggle("favorited"); } else { x.innerHTML = "Favorite"; 16. x.classList.toggle("favorited"); } } but it works fine if i do "var x = document.getElementsId('FAV_btn');" Ill redo do everything anyway, but im just curious, cuz couldnt figure it out tonight.
Liking and disliking posts, images, and more is a common feature in many modern apps. This tutorial shows you one way to do this with JavaScript in your frontend code. We'll use the Faker API to simulate real data in our contacts app and grab the selected contact data when we like or unlike the contact card. This pulls together several concepts from my 8 hour Vanilla JavaScript tutorial found here: ruclips.net/video/EfAl9bwzVZk/видео.html
Very nice! Exactly what I needed to learn! Thank you.
You're welcome!
Very cool video as usual,
the way you structure your code keeps amazes me,
may be set the cursor: pointer; on the like button (see, I'm smart 🤓)
since I have nothing more to add, I just wanted to mention that adding a lot of event listeners may reduce the performance to a certain degree (not in this project),
so alternatively we can add one event listener on the container and from within we can check event.target for the actual element we're looking for like this:
main.addEventListener('click', event =>{
// Check if clicked element is a like button by looking into its class list
if(event.target.classList.contains('like')){
// the same logic for the like click handler goes here
}
});
the down side is this handler will be triggered on wherever you click on the container element but still makes the app lighter.
Thank you Dave for keeping our brains working 🤯
Once again, great feedback Ahmad. Thanks! Yes, a vast amount of event listeners could cause an issue. In such a case, your alternative looks like it would be a good solution! 🚀
@@DaveGrayTeachesCode Thanks Dave,
Edit: I forgot to mention another benefit of adding the listener on the container is that we eliminate the need to re-adding the listeners when loading a new set of the elements (like in load more/pagination cases)
Is this approach what is called "Event Delegation"?
@@CynthiaSotoCaballerolYEAHl I've been using this technique for a long time ago and just now I know that it has a name "Event Delegation" 🤦♂️
anyway, if anyone is interested in this topic this link might be useful:
www.sitepoint.com/javascript-event-delegation-is-easier-than-you-think/
Thanks for mentioning that
@@ahmad-murery thanks for your answer my friend and your feedback about event delegation vs. listeners
The intro is awesome!
Thanks!
Thank you so much Mr. Dave for all the golden information !
You're welcome!
Awesome as always 👍😀
Thank you! 🙏
Thank you for the tutorial. Where did you copy your svg code from?
Hi Beth, it has been so long ago I cannot remember. I had it for a few years prior before making this tutorial almost a year ago. You can Google for free resources. Sorry I'm not more help on this one!
@@DaveGrayTeachesCode That's ok! thanks for the quick reply!
Thank you for this great tutorial. I would like to add the SVG icon on the top right of a table. However, it always shows outside. After a bit of research, it seems like tables and divs do not play well together. Any idea on how I can get around this?
You're welcome! There is no issue with using a div or divs with a table element. I think you will learn how to do this by learning about CSS position: ruclips.net/video/zqg4A6g9GfA/видео.html
How can you use createCardElements() at the top when function expressions can not be used before you have created them?
Good question! Everything is contained inside of a function definition. The definitions are read before a function is called. If I called the function in the global scope, it would be a problem. A detailed look at scope here: ruclips.net/video/_E96W6ivHng/видео.html
@@DaveGrayTeachesCode Sorry for asking too many questions. If I understand correctly, at first the variables are hoisted to the top. So elemObj and const createCardElement are both hoisted to the top. Now createCardElement is read, its going to assign elemObj to createCardElements()?
@@streamx2 Notice initApp() is defined before the listener that calls it. No functions are called in the global scope. initApp() is called by the event listener. All function definitions are read as the script is processed. All functions are then only called within other functions. In that regard, they are not called before their definitions. Arrow functions do not get hoisted. Hoisting does not apply to const. (updated this after a quick review!)
I was looking for favorite image function as I had already done api fetching etc, posting the image with author and title, but then i saw how this code looks like and now I feel miserable by looking at mine, cuz it is just not this clean as i didnt even know i can render api data like this and all... To even use the favorite function id have to probably rewrite my whole code. ouch. Anyway ill probably now watch the whole tutorial of 8h when i have time, just to get to know how to use everything better...
Glad I could help! Thanks for the note. 🙏🚀
@@DaveGrayTeachesCode i should say thank you instead, the way you show to render fetched data is what I definitely need to learn, would make it way easier to work with this all for me
test
Ah hello again, Since ive been doing image scroller and the fav function has been kicking me a lot where it hurts, can someone tell me why, i get
"custom.js:16 Uncaught TypeError: Cannot read property 'toggle' of undefined
at myFunctionFavo (custom.js:16)
at HTMLButtonElement.onclick (index.html:31)
myFunctionFavo @ custom.js:16
onclick @ index.html:31"
code parts below--------
html:
21. Favorite
js:
function myFunctionFavo() {
var x = document.getElementsByClassName('image__favorite fav_button');
if (x.innerHTML === "Favorite") {
x.innerHTML = "Favorited";
x.classList.toggle("favorited");
} else {
x.innerHTML = "Favorite";
16. x.classList.toggle("favorited");
}
}
but it works fine if i do "var x = document.getElementsId('FAV_btn');"
Ill redo do everything anyway, but im just curious, cuz couldnt figure it out tonight.