I’m trying to concatenate a string of <optgroup>
s and <option>
s based on categories and subcategories.
Currently, I am getting a string that has all the categories first then all of the subcategories. I need it to go category > subcategories for said category
etc.
The backend has two tables, main categories, and subcategories.
Subcategory Table
id
title
main_category_id
Main Category Table
id
title
In my code below, I am trying to loop through the main categories, adding them to an <optgroup>
. Before moving to the next main category, I am getting the subcategories for each and adding them as <option>
s.
let select = document.querySelector("#category");
let str = "";
async function getMainCategories() {
const categoriesURL = "INSERT_URL"
await fetch(categoriesURL)
.then(response => response.json())
.then(async categories => {
await categories.sort(function(a, b) {
var nameA = a.title.toUpperCase(); // ignore upper and lowercase
var nameB = b.title.toUpperCase(); // ignore upper and lowercase
if (nameA < nameB) {
return -1;
}
if (nameA > nameB) {
return 1;
}
// names must be equal
return 0;
}).map(async cat => {
str += `<optgroup label="${cat.title}">`;
await getSubcategories(cat.id);
console.log(str)
str += '</optgroup>';
})
});
select.innerHTML = "<option disabled selected>Select a category</option>" + str;
}
async function getSubcategories(id) {
let subcategoriesURL = `INSERT_URL?cat_id=${id}`;
await fetch(subcategoriesURL)
.then(response => response.json())
.then(subcategories => {
subcategories.sort(function(a, b) {
var nameA = a.title.toUpperCase(); // ignore upper and lowercase
var nameB = b.title.toUpperCase(); // ignore upper and lowercase
if (nameA < nameB) {
return -1;
}
if (nameA > nameB) {
return 1;
}
// names must be equal
return 0;
}).map(sub => {
return str += `<option value="${sub.id}">${sub.title}</option>`;
})
});
}
getMainCategories();