I'm trying to create <optgroup>s that have subcategories pulled from an API. Currently, only the <optgroup>s are populating, but not the subcategories.
let select = document.querySelector("#category");
const categoriesURL = "INSERT_URL"
let str = "";
fetch(categoriesURL)
.then(response => response.json())
.then(data => {
data.forEach(category => {
let categoryTitle = category.title;
str += `<optgroup label=${categoryTitle}></optgroup>`
category.subcategories.forEach(sub => {
let subcategories_id = sub.subcategories_id;
let subcategoriesURL = `INSERT_URL/${subcategories_id}`;
fetch(subcategoriesURL)
.then(response => response.json())
.then(subData => {
str += `<option value=${sub.subcategories_id}>` + subData.title + "</option>";
})
})
})
select.innerHTML = "<option disabled selected>Select a category</option>" + str;
});
When defining your
optgroupin the string, you immediately open and close the optgroup, effectively putting every option after the optgroup.Leave the
optgroupopen in the aforementioned string.However, the hard part is closing the string after all the
fetchrequests on the subcategories are complete. We can accomplish this withPromise.allandArray#map.Loop over all the subcategories with
mapand returnPromisethatfetchreturns in the loop. When all thefetchrequests are done the code will continue to thethenblock that follows thePromise.allfunction. In that block you will have the ids and titles of all your subcategories collected in an array. Loop over array to append to your string.After the loop, close the
optgroupelement.Though, overall this a very expensive script as it will create a lot of requests. If you have any say over the backend, then I'd advice that you send the all the data back in a single request and create your list based on that result.