I have some JSON data that is a serious of objects inside an array that is fetched and outputted via PHP json_encode()
and the javascript fetch()
API. This data includes the results of a MySQL join on a many-to-many pivot linking table. Essentially it is outputting specific image board data where you can have the same image on multiple boards and, obviously, multiple boards. This all works as expected.
The Context
An example of this data is:
[
{board_id: 428, board_name: 'tree board', image_id: 269}
{board_id: 428, board_name: 'tree board', image_id: 292}
{board_id: 426, board_name: 'Urban and City', image_id: 269}
{board_id: 426, board_name: 'Urban and City', image_id: 292}
{board_id: 426, board_name: 'Urban and City', image_id: 410}
{board_id: 365, board_name: 'random stuff', image_id: 269}
{board_id: 365, board_name: 'random stuff', image_id: 292}
]
Within a then()
method of the JavaScript fetch()
I am trying to create some button elements based on this data and append them to a parent wrapper, where only one element is created per board_id
value.
An example of what this outputted HTML should look like:
<div >
<button value="428">tree board</button>
<button value="426">Urban and City</button>
<button value="365">random stuff</button>
</div>
The Issue
What I can't work out is how append the element inside the wrapper div (ideally with template strings) so only one instance of each board_id
value gets a button element?
In pseudo code like this:
let newButton = `
<button value="${board_id}">${board_name}</button>
`
I appreciate I need to do this inside a loop — the array of objects is assigned to a json
variable in the then()
method:
let wrapper = document.querySelector('.wrapper'); // the wrapper div
json.forEach( i => {
let boardName = i.board_name;
let boardId = i.board_id;
// -- somehow only only create a button on one instance of each board_id value
// -- append the single instance of the button inside the wrapper div
})
I'm thinking when it comes to appending the templates strings I would need to utilise something like this inside the loop?
wrapper.insertAdjacentHTML('afterbegin', newButton);
Question Summary
How do I output/create a button element for only one instance of each board_id
value, and then append this inside the parent wrapper?
Any help or suggestions hugely appreciated
CodePudding user response:
To ensure that buttons are captured in order create two separate arrays: one to contain existing board ids, the other to contain the buttons HTML.
Use a loop. If the board id isn't in the ids array add it, and then add in the button HTML to the buttons array. Then just join
the buttons array up, and add the complete HTML string to the wrapper element.
const data=[{board_id:428,board_name:"tree board",image_id:269},{board_id:428,board_name:"tree board",image_id:292},{board_id:426,board_name:"Urban and City",image_id:269},{board_id:426,board_name:"Urban and City",image_id:292},{board_id:426,board_name:"Urban and City",image_id:410},{board_id:365,board_name:"random stuff",image_id:269},{board_id:365,board_name:"random stuff",image_id:292}];
const wrapper = document.querySelector('.wrapper');
const ids = [];
const buttons = [];
for (const { board_id, board_name } of data) {
if (!ids.includes(board_id)) {
ids.push(board_id);
buttons.push(`<button value=${board_id}>${board_name}</button>`);
}
}
wrapper.innerHTML = buttons.join('');
<div >
</div>
Additional documentation