1

it is my first question in the community

Hello everyone! Now i am practicing JS classes. In the code below i want to make cards of products with with courses of programming languages, i have created array with data which must be added to html body ,see Render class

const div = document.getElementById('app')
class Arguments {
constructor(title, img, depiction, price) {
    this.title = title
    this.img = img
    this.depiction = depiction
    this.price = price
}
}

class Render {
cards = [
    new Arguments('Python BootCamp', 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcR7qKCjl9JJDnFDvf-U4Sv_YR5iXWGZbu-QRXNDZ5peS_Nusg8Sh8fb5lk5IbH9_MqSIIE&usqp=CAU', 'In this Complete Python course, you will learn everything you need to know about Python programming. You will start from very basics towards to the advance', 0.00,),
    new Arguments('JavaScript Crash Course', 'https://i.ytimg.com/vi/nN_qBdgmQpw/maxresdefault.jpg', 'A crach course by professional JS-DEVELOPER who"s wage $10000+', 300.00),new Arguments('JAVA COURSE', 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSvZ2DvlygW--TMKhrSO4SfA-6Op1QmVUXmh2dqtGxbHxPyvYH9elzpu-xGy2FOPac9VcE&usqp=CAU', 'A profi"s java totrial ', 70.00,),
]
render() {
    const ul = document.createElement('ul')
    const li = document.createElement('li')
        for (const elm of this.cards) {
            li.classList.add = 'card'
            li.innerHTML = `<h1>${elm.title}</h1><img src='${elm.img}'><p>${elm.depiction}</p><h3>${elm.price}</h3>`
            ul.append(li)
        }
    div.append(ul)
}
}
const Project = new ProductsList_Render
Project.render()

I encounter with a problem ! It adds only last element of the array but we can see the length of cards is 3. I thought that for-of loop returns only one result not more but...

let array=[1,2]
for (const iterator of array) {
    console.log(iterator);
} 

How to fix it.

JS Member
  • 21
  • 1
  • PS: the `cards ` array has nothing to do with that `Render` class. Move that away, outside of that class. Pass as argument to the contructor rather. – Roko C. Buljan Jul 24 '21 at 07:50
  • 1
    put `const li = document.createElement('li')` inside the loop – banyudu Jul 24 '21 at 07:51
  • Your types should not depend on global state. Change `div` from a global variable to a parameter of `render()`. – Dai Jul 24 '21 at 07:51
  • Move that `const li = document.createElement('li')` inside the loop. Right now you are overwriting it each time loop iterates. – Goran.it Jul 24 '21 at 07:51
  • 2
    [Duplicate](//google.com/search?q=site%3Astackoverflow.com+js+only+one+element+gets+appended+in+loop) of [JavaScript: for loop append element in several places](/q/32855524/4642212). The issue has nothing to do with classes or arrays. @Goran.it No, nothing is being overwritten; the same element is appended multiple times. Appending an element which is already appended will remove the element first; an element cannot exist in two places at once. – Sebastian Simon Jul 24 '21 at 07:52
  • @SebastianSimon content of the LI is overwritten, while the element itself is just being added again (like you said its removed and added again) – Goran.it Jul 24 '21 at 07:55

1 Answers1

0

No, there's a little mistake in your code. Have a look into the below corrected one (Check my comments as well).

The problem was, you were using const li = document.createElement('li'); before the for loop. As we know we have to add li elements N number of times for a single ul element so it shouldn't be outside of for loop (It's like we are creating only 1 element so it was taking the last one -> overriding the old ones).

I updated (moved lines) and tried to run at https://www.w3schools.com/code/tryit.asp?filename=GSS60TDWYWL8, it works.

// Make sure you have an element with id `app` in HTML body.
const div = document.getElementById('app'); 

class Arguments {
    constructor(title, img, depiction, price) {
        this.title = title
        this.img = img
        this.depiction = depiction
        this.price = price
    }
}

class Render {
    cards = [
        new Arguments('Python BootCamp', 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcR7qKCjl9JJDnFDvf-U4Sv_YR5iXWGZbu-QRXNDZ5peS_Nusg8Sh8fb5lk5IbH9_MqSIIE&usqp=CAU', 'In this Complete Python course, you will learn everything you need to know about Python programming. You will start from very basics towards to the advance', 0.00,),
        new Arguments('JavaScript Crash Course', 'https://i.ytimg.com/vi/nN_qBdgmQpw/maxresdefault.jpg', 'A crach course by professional JS-DEVELOPER who"s wage $10000+', 300.00),new Arguments('JAVA COURSE', 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSvZ2DvlygW--TMKhrSO4SfA-6Op1QmVUXmh2dqtGxbHxPyvYH9elzpu-xGy2FOPac9VcE&usqp=CAU', 'A profi"s java totrial ', 70.00,),
    ]
    render() {
        const ul = document.createElement('ul')
        // const li = document.createElement('li');
        for (const elm of this.cards) {
                let li = document.createElement('li'); // Use the above commented line here     
                li.classList.add('card');  // Not -> li.classList.add = 'card'
                li.innerHTML = `<h1>${elm.title}</h1><img src='${elm.img}'><p>${elm.depiction}</p><h3>${elm.price}</h3>`
                ul.append(li)
            }
        div.append(ul)
    }
}

const Project = new Render(); // Instantiation
Project.render(); // Call render() method

Thanks.


For better naming conventions to use in JS programming, read this doc https://www.robinwieruch.de/javascript-naming-conventions.

hygull
  • 8,464
  • 2
  • 43
  • 52