CodeConnoisseur
CodeConnoisseur

Reputation: 1869

Loop over an Array of Objects and display only object property at a time in HTML using Javascript

I have an array of objects. Within the objects are 2 properties: "quote" and "author". I have a container div in which I want the quotes to display one at a time on an interval of every 2 seconds. Right now it is displaying one letter at a time rather than one (quote + author) at a time. How do I get it to display one (quote + author) at a time?

"use strict";

/*Read JSON quotes file*/
let mainContainer = document.querySelector('.quotes');


let quotesList = [
    {
        "quote": "Whether you think you can or you think you can’t, you’re right.",
        "author": "—Mother Teresa",
    },
    {
        "quote": "Act as if what you do makes a difference. It does.",
        "author": "—William James",
    },
    {
        "quote": "What you get by achieving your goals is not as important as what you become by achieving your goals.",
        "author": "—Zig Ziglar",
    },
];

var counter = 0;
let allQuotes;

quotesList.map(quote => {
    allQuotes = `${quote.quote} ${quote.author}`;
})

function next_quote() {
    mainContainer.innerHTML =  allQuotes[counter %  allQuotes.length];
    counter += 1;
}

setInterval(next_quote, 2000);

HTML:

<div class="quotes">Place quote here</div>

Upvotes: 0

Views: 125

Answers (3)

tonitone120
tonitone120

Reputation: 2290

I've minimally modified your existing code as I thought it would be helpful for you to learn.


Explanation

allQuotes had not been initialised (assigned a value). I've assigned it an empty array.

.map returns an array whose items will be the return value from .map's callback function (the function we pass as an argument to .map). The callback function is called as many times as there are items on the array (array.length).

I've made it so every item of quotesList ({quote: ..., author: ...}) is added to the allQuotes array.

Finally, in next_quote you can see how we step into the item of the allQuotes array with allQuotes[counter] - which returns the {quote: ..., name: ...}. Then, you can see how we further step in it with .quote or .author - retrieving the values of these properties.

Once the counter is the same as the number of quotes, it resets to zero.

Code

let quotesList = [
    {
        "quote": "Whether you think you can or you think you can’t, you’re right.",
        "author": "—Mother Teresa",
    },
    {
        "quote": "Act as if what you do makes a difference. It does.",
        "author": "—William James",
    },
    {
        "quote": "What you get by achieving your goals is not as important as what you become by achieving your goals.",
        "author": "—Zig Ziglar",
    },
];

var counter = 0;
let allQuotes = [];

quotesList.map((item, index, array) => {
    allQuotes[index] = item;
})

function next_quote() {
    console.log(allQuotes[counter].quote + '\n' + allQuotes[counter].author);
    counter += 1;
    if (counter === allQuotes.length) {
        counter = 0;
    } 
}

function start() {
    console.log(allQuotes[counter].quote + '\n' + allQuotes[counter].author);
    counter += 1;
    setInterval(next_quote, 2000);
}

start();


Refactored into one function - happy to explain if you want

let quotesList = [
    {
        "quote": "Whether you think you can or you think you can’t, you’re right.",
        "author": "—Mother Teresa",
    },
    {
        "quote": "Act as if what you do makes a difference. It does.",
        "author": "—William James",
    },
    {
        "quote": "What you get by achieving your goals is not as important as what you become by achieving your goals.",
        "author": "—Zig Ziglar",
    },
];

function start() {
    let quoteCounter = 0;
    function currentQuote() {
        console.log(quotesList[quoteCounter].quote + '\n' + quotesList[quoteCounter].author);
    }
    for (; ; quoteCounter++) {
        if (quoteCounter === 0) {
            currentQuote();
            continue;
        }
        setInterval(function() {
                currentQuote();
                quoteCounter++;
                quoteCounter === quotesList.length ? quoteCounter = 0 : null
            }, 2000);
        break;
    }
}

start();

Upvotes: 1

Brian Lee
Brian Lee

Reputation: 18187

Here's a simplified working example based off your code that doesn't need to map the quotes list:

let quotesList = [
    {
        "quote": "Whether you think you can or you think you can’t, you’re right.",
        "author": "—Mother Teresa",
    },
    {
        "quote": "Act as if what you do makes a difference. It does.",
        "author": "—William James",
    },
    {
        "quote": "What you get by achieving your goals is not as important as what you become by achieving your goals.",
        "author": "—Zig Ziglar",
    },
];

let index = 0;

setInterval(() => {
  document.body.innerHTML = `${quotesList[index].quote} ${quotesList[index].author}`;
  index += 1;
  if (index === quotesList.length) {
    index = 0;
  }
}, 2000);

Upvotes: 1

Majed Badawi
Majed Badawi

Reputation: 28404

.map returns an array, you can fix it as follows:

"use strict";

/*Read JSON quotes file*/
let mainContainer = document.querySelector('.quotes');


let quotesList = [
    {
        "quote": "Whether you think you can or you think you can’t, you’re right.",
        "author": "—Mother Teresa",
    },
    {
        "quote": "Act as if what you do makes a difference. It does.",
        "author": "—William James",
    },
    {
        "quote": "What you get by achieving your goals is not as important as what you become by achieving your goals.",
        "author": "—Zig Ziglar",
    },
];

var counter = 0;
let allQuotes;

allQuotes = quotesList.map(quote => {
    return `${quote.quote} ${quote.author}`;
})

function next_quote() {
    mainContainer.innerHTML =  allQuotes[counter %  allQuotes.length];
    counter += 1;
}

setInterval(next_quote, 2000);
<div class="quotes">Place quote here</div>

Upvotes: 1

Related Questions