0

I'm relatively new to OOP and want to create some simple HTML out of each object. Essentially, I have these objects:

const slides = {
  "slide1": {
    "image": "images/projects/authorising-engineers/winbledon-centre-court.jpg",
    "caption": "Wimbledon Centre Court"
  },
  "slide2": {
    "image": "images/projects/authorising-engineers/waterloo-train-station.jpg",
    "caption": "Waterloo Train Station"
  },
  "slide3": {
    "image": "images/projects/authorising-engineers/test.jpg",
    "caption": "Das Lion"
  },
  "slide4": {
    "image": "images/projects/authorising-engineers/some4.jpg",
    "caption": "the four"
  },
  "slide5": {
    "image": "images/projects/authorising-engineers/some5.jpg",
    "caption": "no five"
  }
}

And I just want the HTML to output this, where figure 1, 2 and 5 have unique classes:

"<figure class='individual-slide current'><img src='images/projects/authorising-engineers/winbledon-centre-court.jpg' style = 'background-image: url(images/projects/authorising-engineers/winbledon-centre-court.jpg)'><figcaption>Wimbledon Centre Court</figcaption></figure>"
"<figure class='individual-slide next'><img src='images/projects/authorising-engineers/waterloo-train-station.jpg' style = 'background-image: url(images/projects/authorising-engineers/waterloo-train-station.jpg)'><figcaption>Waterloo Train Station</figcaption></figure>"
"<figure class='individual-slide'><img src='images/projects/authorising-engineers/test.jpg' style = 'background-image: url(images/projects/authorising-engineers/test.jpg)'><figcaption>Das Lion</figcaption></figure>"
"<figure class='individual-slide'><img src='images/projects/authorising-engineers/some4.jpg' style = 'background-image: url(images/projects/authorising-engineers/some4.jpg)'><figcaption>the four</figcaption></figure>"
"<figure class='individual-slide previous'><img src='images/projects/authorising-engineers/some5.jpg' style = 'background-image: url(images/projects/authorising-engineers/some5.jpg)'><figcaption>no five</figcaption></figure>"

The closest I could achieve so far is the below - the following code successfully creates the HTML, but gives no control if I want to customise the nth item (i.e. adding classes to objects 1, 2 and 5):

    // create the innerHtml
    for (const slide in slides) {
      let theHtml =
        "<figure class='individual-slide'><img src='"
        + slides[slide].image
        + "' style = 'background-image: url("
        + slides[slide].image
        + ")'><figcaption>"
        + slides[slide].caption
        + "</figcaption></figure>";
}

Codepen of the above: https://codepen.io/ns91/pen/vYYZKKB

I've thus attempted to use a classic for loop so I can add if statements for the nth item (i.e. if i = 0, add the first class, etc), although this doesn't seem to work even without them:

// create the innerHtml
for (const i = 0; i < Object.keys(slides).length; i++) {

  let theHtml =
    "<figure class='individual-slide'><img src='"
    + slides[slides][i].image
    + "' style = 'background-image: url("
    + slides[slides[i].image
    + ")'><figcaption>"
    + slides[slides[i].caption
    + "</figcaption></figure>";
}

console.log(theHtml);

CodePen: https://codepen.io/ns91/pen/oNNwLzR

So my questions are:

  1. What's wrong with my code
  2. How can I loop through each object but add the 'current', 'next' and 'previous' classes
  3. And what's the best way of looping through objects like this?

Any advice would be much appreciated. Thanks for any help here

2
  • Not directly related, but why not use an array? Commented Oct 26, 2019 at 0:28
  • You can use Object.entries(obj).map(([value, key], index) => {...generate html...} if you need key value and index Commented Oct 26, 2019 at 0:31

2 Answers 2

1

tried the last example - you have some syntax errors in your code, e.g. slides[slides[i].image. Try using code editor with syntax highlight, e.g. VSCode

this would be the most straightfowrad way to fix 2nd pen

  Object.keys(slides).forEach((key, index) => {
    let additionalClass = ""
    if (index === 0) {
      additionalClass = " current"
    } else if (index === 1) {
      additionalClass = " next"
    } else if (index === 4) {
      additionalClass = " previous"
    }
    let theHtml =
      "<figure class='individual-slide"+additionalClass+"'><img src='"
      + slides[key].image
      + "' style = 'background-image: url("
      + slides[key].image
      + ")'><figcaption>"
      + slides[key].caption
      + "</figcaption></figure>";

    console.log(theHtml);

  })

so answering your 2nd question, you get index of the object passing 2nd parameter to the forEach callback and use it in your logic to determine class name you want

3rd question: Object.keys(slides) to iterate over key names, or Object.values(slides) to iterate over values ({ image: '...', caption: '...' } object in your case)

Sign up to request clarification or add additional context in comments.

Comments

1

If you specifically want image 1, 2 and 5 to have unique classes, you can use if statements in your loop.

Your loops are perfectly fine btw.

So inside your loop:

if slide+1 == 1 || slide+1 == 2 || slide+1 == 5):
... add your classes

We add 1 since the index starts at 0.

Otherwise, a better solution is to add a key into your object that signifies that the object needs special treatment.

const slides = {
  "slide1": {
    "image": "images/projects/authorising-engineers/winbledon-centre-court.jpg",
    "caption": "Wimbledon Centre Court",
    "unique": True
  },
  "slide2": {
    "image": "images/projects/authorising-engineers/waterloo-train-station.jpg",
    "caption": "Waterloo Train Station"
  "unique": True
  },
  "slide3": {
    "image": "images/projects/authorising-engineers/test.jpg",
    "caption": "Das Lion"
  },
  "slide4": {
    "image": "images/projects/authorising-engineers/some4.jpg",
    "caption": "the four"
  },
  "slide5": {
    "image": "images/projects/authorising-engineers/some5.jpg",
    "caption": "no five",
    "unique": True
  }
}

And then use the same if statement as above, but just checking

if slides[slide].unique

2 Comments

thanks - although how is there nothing wrong with my 2nd code? it doesn't log anything into the console: codepen.io/ns91/pen/oNNwLzR
It doesnt console log anything because the keyword "let" is bounded by the scope of the function. If you console log inside your loop, youll see something.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.