0

My goal is to "pause" the EventListener function in order to get something done by calling another function (getCategoriesIDs) that returns a value that I will use to continue the EventListener function execution.

When I log the categoriesIDtoNameMapped after the execution it comes out as UNDEFINED.

Would greatly appreciate your help.

form.addEventListener("submit", async (e) => {

//do something

try {
    let categoriesIDtoNameMapped = await getCategoriesIDs()
    console.log(categoriesIDtoNameMapped)
} catch (err) {
    console.log(err)
}
            
//do something with the categoriesIDtoNameMapped

}

function getCategoriesIDs() {
    fetch('http://localhost:1337/api/categories', {
        method: 'GET',
        headers: {
            'Content-type': 'application/json',
            Authorization: `Bearer ${JWT_TOKEN}`
        }
    })
    .then((response) => {
        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }
        return response.json();
    })
    .then((response) => {
        const categoriesIDtoNameMapped = {}
        for (let i = 0; i < response.data.length; i++) {
            categoriesIDtoNameMapped[response.data[i].id] = response.data[i].attributes.name
        }
        return new Promise(resolve => {
            resolve(categoriesIDtoNameMapped)
        });
    });
}
Joao Pereira
  • 75
  • 2
  • 11

1 Answers1

1

Your getCategoriesIDs needs to be an async function for you to await something on it.

To fix this you need make getCategoriesIDs as async function and use await for fetch

async function getCategoriesIDs() {
    const response = await fetch('http://localhost:1337/api/categories', {
        method: 'GET',
        headers: {
            'Content-type': 'application/json',
            Authorization: `Bearer ${JWT_TOKEN}`
        }
    })
    if (!response.ok) {
        throw new Error(`HTTP error! Status: ${response.status}`);
    }
    const responseJson = await response.json();
    const categoriesIDtoNameMapped = {}
        for (let i = 0; i < response.data.length; i++) {
            categoriesIDtoNameMapped[responseJson.data[i].id] = response.data[i].attributes.name
        }
    return categoriesIDtoNameMapped;
}
Yatin Gupta
  • 653
  • 5
  • 12
  • 1
    Pretty much exactly that I was going to post :) – ControlAltDel Jan 05 '23 at 20:51
  • You don't need to do this, simple `return` would be enough – Konrad Jan 05 '23 at 20:52
  • Ty for your help but I dont think this function needs to be async since the invoking function is already async and I call this function with await, so it will pause the execution to execute this function and then resume after. This is my understanding and it is working as intended. Correct me if I am wrong. – Joao Pereira Jan 05 '23 at 20:57
  • 1
    @JoaoPereira You are wrong. This function needs to be async, as it uses `await` on `response`. – ControlAltDel Jan 05 '23 at 21:01
  • ^This is my understanding as well. Are you sure you are not getting {} as response without async await @JoaoPereira – Yatin Gupta Jan 05 '23 at 21:04
  • I can see that not making it async could make the fetch execute after the return, returning an empty object. But that is not the case in my code, it is working as intended. Why is that so? Is it because the fetch request is taking very little time since its locally? Im trying to wrap my head around the async nature of js – Joao Pereira Jan 05 '23 at 22:33
  • Thank you for your help! Still not understanding why my other solution below was also working, now I'm curious... – Joao Pereira Jan 05 '23 at 22:53
  • Maybe it's due to fetch taking very little time? Maybe try adding a timeout inside .then to confirm ? – Yatin Gupta Jan 05 '23 at 23:14