Instructions on incorporating a created object from a class into an array by utilizing a method specifically made within that class

After implementing a Book class which includes a method to add a single object to an array upon clicking a button, I noticed that when the button is clicked, it adds the button itself rather than the expected object.

See the code snippet below:

class Book {
    constructor(title, author, year, poster){
        this.title = title;
        this.author = author;
        this.year = year
        this.poster = poster
    }
    addToFavourite(){
        favouriteBooks.push(this)
    }

}
const favouriteBooks = []
const booksList = [ new Book('you don\'t know js', ' Kyle Simpson', 2014, 'https://images-na.ssl-images-amazon.com/images/I/41T5H8u7fUL._SX331_BO1,204,203,200_.jpg'), 
                    new Book('javascript the definitive guide', 'David Flanagan', 1996, 'https://images-na.ssl-images-amazon.com/images/I/51wijnc-Y8L._SX379_BO1,204,203,200_.jpg'), 
                    new Book('Eloquent JavaScript', 'Marijn Haverbeke', 2011, 'https://eloquentjavascript.net/img/cover.jpg')
                ]


const renderBooks = (booksToRender)=>{  
    booksToRender.forEach(book =>{
        //elements to be created
        const bookContainer = document.createElement('article')
        const posterContainer = document.createElement('div')
        const poster = document.createElement('img')
        const bookTitle = document.createElement('h2')
        const bookYear = document.createElement('p')
        const bookAuthor = document.createElement('h3')
        const addToFavouriteBtn = document.createElement('button')

        //elements setup
        addToFavouriteBtn.addEventListener('click', book.addToFavourite)
        poster.src = book.poster
        bookTitle.textContent = book.title
        bookYear.textContent = book.year
        bookAuthor.textContent = book.author
        addToFavouriteBtn.textContent = 'Add to favourite'

        //elements render
        posterContainer.append(poster)
        bookContainer.append(posterContainer, bookTitle, bookYear, bookAuthor, addToFavouriteBtn)
        document.querySelector('main').append(bookContainer)
        
    })
}

renderBooks(booksList)

https://i.sstatic.net/aVQQY.png

Answer №1

When the click event triggers, the reference of this points to the button, not the book itself. To resolve this issue, you must bind the book object to the method. So instead of

addToFavouriteBtn.addEventListener('click', book.addToFavourite)
, it should be changed to
addToFavouriteBtn.addEventListener('click', book.addToFavourite.bind(book))
for it to function correctly.

class Book {
    constructor(title, author, year, poster){
        this.title = title;
        this.author = author;
        this.year = year
        this.poster = poster
    }
    addToFavourite(){
        favouriteBooks.push(this)
        // just demonstration
        console.clear();
        console.log("---Favourite Books:---\n", favouriteBooks);
    }

}
const favouriteBooks = []
const booksList = [ new Book('you don\'t know js', ' Kyle Simpson', 2014, 'https://images-na.ssl-images-amazon.com/images/I/41T5H8u7fUL._SX331_BO1,204,203,200_.jpg'), 
                    new Book('javascript the definitive guide', 'David Flanagan', 1996, 'https://images-na.ssl-images-amazon.com/images/I/51wijnc-Y8L._SX379_BO1,204,203,200_.jpg'), 
                    new Book('Eloquent JavaScript', 'Marijn Haverbeke', 2011, 'https://eloquentjavascript.net/img/cover.jpg')
                ]


const renderBooks = (booksToRender)=>{  
    booksToRender.forEach(book =>{
        //elements to be created
        const bookContainer = document.createElement('article')
        const posterContainer = document.createElement('div')
        const poster = document.createElement('img')
        const bookTitle = document.createElement('h2')
        const bookYear = document.createElement('p')
        const bookAuthor = document.createElement('h3')
        const addToFavouriteBtn = document.createElement('button')

        //elements setup
        addToFavouriteBtn.addEventListener('click', book.addToFavourite.bind(book))
        poster.src = book.poster
        bookTitle.textContent = book.title
        bookYear.textContent = book.year
        bookAuthor.textContent = book.author
        addToFavouriteBtn.textContent = 'Add to favourite'

        //elements render
        posterContainer.append(poster)
        bookContainer.append(posterContainer, bookTitle, bookYear, bookAuthor, addToFavouriteBtn)
        document.querySelector('main').append(bookContainer)
        
    })
}

renderBooks(booksList)
<main></main>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Doing server side function calls from the client in NodeJs

I recently embarked on a journey to learn web development and am eager to make server-side data changes when invoking client functions. Take a look at my sample server setup: const fs = require('fs'); const path = require('path'); con ...

Is it not possible to perform multiple queries using values stored in an array?

Essentially, I need the ability for my users to input various SKUs and UPCs (comma-separated) into a search field. From there, I want to generate an array of search values and run through an iterative process to return specific results or logic for each va ...

Unity3D: Troubleshooting a Code Issue

Encountering an issue with my code and struggling to find a solution. I've tried moving my c# script up to the standard assets folder as suggested in my research but it didn't resolve the problem. Any assistance would be greatly appreciated! Than ...

Enhancing the Appearance of HTML Select Dropdowns in JavaFX 2.2 WebEngine

I am currently working on a project that is unable to be updated to Java 1.8 to support the latest JavaFX version. While this may or may not impact the issue I am facing, I have been exploring various solutions from the internet to customize the look and f ...

Enhance Odoo Conversations (mail)

I've been attempting to customize the Odoo discussions, but have hit a roadblock. Here is my goal: https://i.sstatic.net/1lJnc.png I am adding messages using the "New Message" button to an Odoo module (in class mro.order). The messages are appearing ...

Revolutionizing the method of projecting a texture onto a halfsphere in three.js projects

I am currently working on a project in three.js where I am trying to project an image onto the inside of a halfsphere. The half sphere is created using the following code: const geometry = new THREE.SphereGeometry(Component.radius, this.resolution, this.re ...

Tips for saving a text input from scanf into an array

#include<stdio.h> #include<string.h> #include<stdlib.h> int main(){ char *array[3]; scanf("%s",----); // Input is james. return 0; } Is there a way to input the string "james" and store it in array[1] so that it is equival ...

How can I use jQuery to programmatically submit a form?

I created a simple form that makes an ajax POST request when submitted, sending data from the form. The form itself is pretty straightforward. <form id="form1"> <input type="text" name="domain" id="field1"> <input type="submit" name ...

Submit form using jQuery after making an AJAX request with jQuery's $

I'm working on the following code: $.get(link, function(data, status) { document.getElementById("test").value = data; }); $('#formtest').submit(); Everything works fine in Firefox, but in Google Chrome the submit is done before t ...

Teaching and arrows within categories

Here is a snippet of the code structure: class patient{ public: char FirstName[30]; char LastName[30]; char SID[20]; }; class Register{ private: int PatientNum; patient List[]; public: void OutputList (); }; Later on, ...

"Latest version of ThreeJS (r160) utilizes ShaderMaterial to render textures

I've been attempting to incorporate a texture into this shader, but it's displaying as black. I suspect there's a small detail I'm overlooking, despite my search yielding no relevant information for ThreeJS version r160. The shader code ...

php comparing two arrays with the similar_text function

I have collected two extensive arrays of product names and prices through scraping, resembling the following: $one=array('grape'=>'0.40','apple'=>'1.20','banana'=>'1.80','lemon&apos ...

Vue fails to receive updates from Firestore until the page is manually refreshed

I set out to develop a task tracker app using Vue. As I neared completion of the project, I encountered an issue - when adding a new task, it would not change the reminder status unless I reloaded the page. Here is the code snippet from my Home.vue file: & ...

Ways to refresh UI in ReactJS without triggering a specific event

In my React application, I am displaying various pictures and GIFs that users can attach to a post. Currently, each image has an onClick handler which triggers either a modal with different options or deletes the picture if the user holds down the ctrl key ...

How to troubleshoot Path Intellisense in VScode when using jsconfig.json for Next.js

In the structure of my project, it looks like this: jsconfig.json next.config.json components |_atoms |_Button.jsx |_Button.module.scss |_... |_... ... Within the jsconfig.json file, I have specified the following settings: { ...

Is Sending an Object to a Function in the Same Scope Inefficient?

Is there a noticeable delay when passing around an object within the same scope? Let's explore Option 1 and Option 2. In Option 1, we work directly with the object, while in Option 2 we follow better encapsulation practices. However, if we were to sti ...

Enable the feature for users to upload images to a specific folder within the Chrome extension without the need for

I need to implement a feature in my Chrome extension that allows users to upload images directly to a specific folder named "upload" without needing a submit button. <form action="/upload"> <input type="file" name="myimages" accept="image/*"> ...

Issue with Electron Remote process failing to take user-defined width and height inputs

I'm currently facing an issue with utilizing remote windows in electron. I am attempting to process user input and use that input to generate a new window with specific width and height. However, when I hit submit, nothing happens. I can't figur ...

Finding an element that lacks both a class and an id, and is not consistently present - what's the trick?

Currently, I am faced with a predicament in my code where a <li> element only appears under specific conditions, making it difficult to apply positioning. This element lacks an id and class attribute, which prevents me from targeting it accurately us ...

Retrieving a designated set of attributes for elements chosen using an element selector

Is there a way to retrieve specific attributes for the first 10 <p> elements in a document using jQuery? I know I can easily get the first 10 elements with $('p').slice(0,10), but I only need certain attributes like innerText for each eleme ...