Can anybody could me explain how I can avoid duplicate my categories? - I'm new in js/API things.
dom-utils.js:
const createCategorySelectOptions = (expense) =>{
const selectOption = document.createElement("option");
selectOption.text = expense.category;
selectOption.value = expense.category;
return selectOption;
}
const createCategorySelectElement = (expenses) =>{
const selectElement = document.createElement("select");
expenses.forEach((expense) => {
selectElement.appendChild(createCategorySelectOptions(expense));
});
return selectElement;
}
export const renderExpensesList = (expenses) => {
const categorySelector = document.querySelector("#category");
categorySelector.appendChild(createCategorySelectElement(expenses));
}
html:
<label id="category"><span>Category</span> </label>
app.js:
import { renderExpensesList } from './dom-utils.js';
let expenses;
const API_URL = "../expenses.json";
fetch(API_URL).then((response) => response.json()).then((data) =>{
expenses = data.map(expense =>{
return {
name: expense.name,
cost: expense.cost,
currency: expense.currency,
category: expense.category,
date: expense.date,
};
});
renderExpensesList(expenses);
})
.catch((err) =>{
});
JSON:
[
{
"name": "cofee",
"cost": "40",
"currency": "PLN",
"category": "food",
"date": "2022-07-16T00:00:00"
},
{
"name": "bread",
"cost": "8",
"currency": "PLN",
"category": "food",
"date": "2022-08-03T00:00:00"
},
{
"name": "cheese",
"cost": "21",
"currency": "PLN",
"category": "food",
"date": "2022-08-03T00:00:00"
},
{
"name": "fuel",
"cost": "320",
"currency": "PLN",
"category": "car",
"date": "2022-08-14T00:00:00"
},
{
"name": "bread",
"cost": "8",
"currency": "PLN",
"category": "food",
"date": "2022-09-01T00:00:00"
},
{
"name": "ham",
"cost": "14",
"currency": "PLN",
"category": "food",
"date": "2022-09-01T00:00:00"
},
{
"name": "butter",
"cost": "6",
"currency": "PLN",
"category": "food",
"date": "2022-09-10T00:00:00"
},
{
"name": "fuel",
"cost": "320",
"currency": "PLN",
"category": "car",
"date": "2022-09-10T00:00:00"
},
{
"name": "car wash",
"cost": "60",
"currency": "PLN",
"category": "car",
"date": "2022-09-10T00:00:00"
}
]
I'm trying to avoid duplicate my categories. Pure JS. Something like that:
It's a matter of finding unique category names in your data. Also you create unneeded number of extra intermediate variables and functions but in reality you could do it in 1 function. Also adding new DOM elements with pure HTML often less verbose and always faster:
const expenses = [{ "name": "cofee", "cost": "40", "currency": "PLN", "category": "food", "date": "2022-07-16T00:00:00"}, { "name": "bread", "cost": "8", "currency": "PLN", "category": "food", "date": "2022-08-03T00:00:00"}, { "name": "cheese", "cost": "21", "currency": "PLN", "category": "food", "date": "2022-08-03T00:00:00"}, { "name": "fuel", "cost": "320", "currency": "PLN", "category": "car", "date": "2022-08-14T00:00:00"}, { "name": "bread", "cost": "8", "currency": "PLN", "category": "food", "date": "2022-09-01T00:00:00"}, { "name": "ham", "cost": "14", "currency": "PLN", "category": "food", "date": "2022-09-01T00:00:00"}, { "name": "butter", "cost": "6", "currency": "PLN", "category": "food", "date": "2022-09-10T00:00:00"}, { "name": "fuel", "cost": "320", "currency": "PLN", "category": "car", "date": "2022-09-10T00:00:00"}, { "name": "car wash", "cost": "60", "currency": "PLN", "category": "car", "date": "2022-09-10T00:00:00"}];
const renderExpensesList = (expenses) => {
const selectElement = document.createElement("select");
selectElement.innerHTML = [...new Set(expenses.map(item => item.category))]
.map(category =>
`<option value="${category}">${category}</option>`
).join('');
document.querySelector("#category").appendChild(selectElement);
}
renderExpensesList(expenses);
<div id="category"></div>
If you are obsessed with speed:
Collect unique names in an array with Array::reduce()
and use Set
to check whether a category name is already added to the array:
const expenses = [{ "name": "cofee", "cost": "40", "currency": "PLN", "category": "food", "date": "2022-07-16T00:00:00"}, { "name": "bread", "cost": "8", "currency": "PLN", "category": "food", "date": "2022-08-03T00:00:00"}, { "name": "cheese", "cost": "21", "currency": "PLN", "category": "food", "date": "2022-08-03T00:00:00"}, { "name": "fuel", "cost": "320", "currency": "PLN", "category": "car", "date": "2022-08-14T00:00:00"}, { "name": "bread", "cost": "8", "currency": "PLN", "category": "food", "date": "2022-09-01T00:00:00"}, { "name": "ham", "cost": "14", "currency": "PLN", "category": "food", "date": "2022-09-01T00:00:00"}, { "name": "butter", "cost": "6", "currency": "PLN", "category": "food", "date": "2022-09-10T00:00:00"}, { "name": "fuel", "cost": "320", "currency": "PLN", "category": "car", "date": "2022-09-10T00:00:00"}, { "name": "car wash", "cost": "60", "currency": "PLN", "category": "car", "date": "2022-09-10T00:00:00"}];
const categories = expenses.reduce((acc, item) => {
const {arr, set} = acc;
set.has(item.category) || set.add(arr[arr.length] = item.category);
return acc;
}, {arr:[], set:new Set}).arr;
console.log(categories);