Home > Software design >  Loop through JSON object properties and show one at a time in a text button every time is clicked -
Loop through JSON object properties and show one at a time in a text button every time is clicked -

Time:10-20

I hope you are well! I'm developing a flashcard web app (concepts definitions) in pure JavaScript to learn the theoretical elements of the degree I'm currently studying, web app dev precisely.

I would like to create flashcards for 6 subjects that contain 5 units each. Since I'm still not able to create a backend system, I've seen I can pull data from a JSON file (or several) that would work as a database. I've created a single button for the flashcards in each unit and the idea is to the get the object properties in the button text one by one, every time I click on it. E.g.:


[
  {
    "subject": "Database",
    "concept": "Relational data model",
    "definition": "An abstract model used to organize and manage the data..."
  },
  {
    "subject": "Database",
    "concept": "Information system",
    "definition": "An integrated set of components for collecting, storing..."
  }
]

After the 1st click the button should show "Relational data model", after the 2nd click "An abstract model used to organize and manage the data...", after the 3rd click "Information system", after the 4th click "An integrated set of components for collecting, storing..." and so on.

I've created this function that works just the way I want but only for an array, not for the properties in an array of objects:


var clicks = 0;
var button = document.querySelector("#myButton");
var buttonText = [
  "Start",
  "Concept 1",
  "Definition 1",
  "Concept 2",
  "Definition 2",
  "Concept 3",
  "Definition 3",
  "And so on...",
];
function showContent() {
  clicks  = 1;
  button.innerHTML = buttonText[clicks];
}
button.addEventListener("click", showContent); 

I've tried several loops and the .forEach function but it would only show me the concept and definition at once instead of one at a time. I've tried different ways but I basically don't know how to loop through properties inside an object and then go to the next object properties each time I click. Maybe my approach is completely wrong and this can be done otherwise?

Once I manage to solve this step, I will then adapt it/ add the necessary code to get the info from the JSON file (I've already tried it but I came across the same problem, it only shows the first concept).

Thank you so much for your time and help!

CodePudding user response:

You can set the current number of click into a variable and use this variable to calculate which items is the current items and wich of the properties you need to print.

Note : You can use Object.entries to retieve either the key and the value and maybe display both to the user

const cards = [
  {
    "subject": "Database",
    "concept": "Relational data model",
    "definition": "An abstract model used to organize and manage the data..."
  },
  {
    "subject": "Database",
    "concept": "Information system",
    "definition": "An integrated set of components for collecting, storing..."
  }
]

const button = document.getElementById("my-button")
let nbButtonClick = 0

button.addEventListener('click', () => {
  const nbItemsPerCard = Object.keys(cards[0]).length
  const currentCardIndex = Math.floor(nbButtonClick / nbItemsPerCard)
  if (currentCardIndex >= cards.length) console.log("No card to print")
  else {
    console.log(Object.values(cards[currentCardIndex])[nbButtonClick % nbItemsPerCard])
    nbButtonClick  
  }
  
})
<button id="my-button">Click me</button>

Here i've print all of the card informations but if you want to only show some properties of your card, you can map through your items and retrieve only the property you want to print !

Example :

const cards = [
  {
    "subject": "Database",
    "concept": "Relational data model",
    "definition": "An abstract model used to organize and manage the data..."
  },
  {
    "subject": "Database",
    "concept": "Information system",
    "definition": "An integrated set of components for collecting, storing..."
  }
]

const mappedCatds = cards.map(card => ({concept: card.concept,definition: card.definition }))

const button = document.getElementById("my-button")
let nbButtonClick = 0

button.addEventListener('click', () => {
  const nbItemsPerCard = Object.keys(mappedCatds[0]).length
  const currentCardIndex = Math.floor(nbButtonClick / nbItemsPerCard)
  if (currentCardIndex >= cards.length) console.log("No card to print")
  else {
    console.log(Object.values(mappedCatds[currentCardIndex])[nbButtonClick % nbItemsPerCard])
    nbButtonClick  
  }
  
})
<button id="my-button">Click me</button>

CodePudding user response:

var clicks = 0;
var button = document.querySelector("#myButton");

var json = `[
  {
    "subject": "Database",
    "concept": "Relational data model",
    "definition": "An abstract model used to organize and manage the data..."
  },
  {
    "subject": "Database",
    "concept": "Information system",
    "definition": "An integrated set of components for collecting, storing..."
  }
]`; 
var arr = JSON.parse(json);
console.log(arr) 
const buttonText = arr.reduce((acc,cur)=>{
    
  for (let key in cur){
                console.log(typeof key)
                console.log(cur[key])
                if(key!="subject"){acc.push(cur[key])}
  }
  
    return acc
},[]);
function showContent() {
  clicks  = 1;
  button.innerHTML = buttonText[clicks];
} 
button.addEventListener("click", showContent); 
  • Related