I have an array of objects, with nested objects:
const data = [{
"operationId": "6357a5bba0de053fb601d573",
"tags": {
"120": {
"title": "ac milan",
"color": "red",
"updated_at": "2022-10-25 08:52:00",
"created_at": "2022-10-25 08:52:00",
"_id": "6357a3b06891976bca0a9215"
},
"121": {
"title": "napoli",
"color": "blue",
"updated_at": "2022-10-25 08:54:12",
"created_at": "2022-10-25 08:54:12",
"_id": "6357a43470761099ce0049e0"
},
}
}, {
"operationId": "6357a5c9a0de053fb601d574",
"tags": {
"118": {
"title": "ac roma",
"color": "red",
"updated_at": "2022-10-25 07:54:19",
"created_at": "2022-10-25 07:54:19",
"_id": "6357962b6891976bca0a920e"
},
"120": {
"title": "ac milan",
"color": "red",
"updated_at": "2022-10-25 08:52:00",
"created_at": "2022-10-25 08:52:00",
"_id": "6357a3b06891976bca0a9215"
},
}
}];
where:
operationId
- id of document;tags
- object with binded to document tags.
Based on the information, I need to display a list of tags in the markup. But the same tag can be attached to different documents (as in the example - the "AC Milan" tag is attached to two documents). In this case, the tag must be rendered once. My current iteration of an array of objects does not take this feature into account, and displays everything in a row, but I don’t really understand how to fix it.
function addExistingTagsToModal(arr) {
let existingTagTitle, existingTagColor, existingTagID;
const constructedData = arr.map(item => {
const operationId = item?.operationId;
const innerValues = Object.values(item.tags);
return innerValues.map(subItem => {
existingTagID = subItem._id;
existingTagTitle = subItem.title;
existingTagColor = subItem.color;
let tagObjMarkup = {
tagMarkup: `<li>${existingTagTitle}</li>`
};
let addedTagList = document.querySelector('.list');
addedTagList.insertAdjacentHTML('afterbegin', tagObjMarkup.tagMarkup);
return {
...subItem,
operationId
}
});
});
}
addExistingTagsToModal(data);
Here is a working example (Codepen). To summarize: in the code above, AC Milan should be displayed 1 time. How to do it?
CodePudding user response:
You just need to keep track of the existing titles, so I created an object const tagTitleDict = {};
and checking a key already in it. If found a key in tagTitleDict
then no need to insert it again in the list <ul></ul>
.
function addExistingTagsToModal(arr) {
let existingTagTitle, existingTagColor, existingTagID;
const tagTitleDict = {};
const constructedData = arr.map((item) => {
const operationId = item?.operationId;
const innerValues = Object.values(item.tags);
return innerValues.map((subItem) => {
existingTagID = subItem._id;
existingTagTitle = subItem.title;
existingTagColor = subItem.color;
if (!(existingTagTitle in tagTitleDict)) {
let tagObjMarkup = {
tagMarkup: `<li>${existingTagTitle}</li>`
};
let addedTagList = document.querySelector(".list");
addedTagList.insertAdjacentHTML("afterbegin", tagObjMarkup.tagMarkup);
tagTitleDict[existingTagTitle] = true;
}
return {
...subItem,
operationId
};
});
});
}
Have adjusted to your codepen
Hope it helps, cheers!