Home > OS >  How to return a promise that resolves customized data from API Javascript
How to return a promise that resolves customized data from API Javascript

Time:04-04

So I'm using the API of National Weather Service to create a weather app. But the fetched data is very complicated, and I need to fetch two different APIs. So I want to write a customized async function that returns a promise, which resolves to an object that contains only the necessary data I need.

I came up with something like this:

async function fetchWeatherAPI(){
    //data that I need
    let data = {};
    
    try {
       const res1 = await fetch(url1);
       const result1 = await res1.json();
       data = {...data , result1.usefulData};
    } catch(error){}

    try {
       const res2 = await fetch(url2);
       const result2 = await res2.json();
       data = {...data, result2.usefulData};
    } catch(error){}

    return new Promise((resolve,reject)=>{
         resolve(data);
    })

}

This code is working for me. But the problem is, what if the APIs reject? How can I handle the error so that I can display the error message in the returned promise? I may want something like this:

return new Promise((resolve,reject)=>{
    if(...) reject(errrorMessage); 
    resolve(data);
})

CodePudding user response:

Just do return data. You're already inside an async function and the return value from that function will be the resolved value of the promise that the async function already returns:

async function fetchWeatherAPI(){
    //data that I need
    let data = {};
    
    const res1 = await fetch(url1);
    const result1 = await res1.json();
    data = {...data , result1.usefulData};

    const res2 = await fetch(url2);
    const result2 = await res2.json();
    data = {...data, result2.usefulData};
    return data;
}

In addition, your catch blocks are silently eating errors and attempting to continue as if nothing went wrong. You probably just want the error to propagate back to the caller so if you just remove your try/catch blocks, that's what will happen.

And, the return new Promise() you have is entirely superfluous and unnecessary (referred to as an anti-pattern). You can just remove it and return data instead.


Note: Since the code you show does not show any dependency between your first and second fetch() calls, you could run them in parallel and perhaps finish them faster.

async function fetchWeatherAPI(){
    //data that I need
    let data = {};

    const [result1, result2] = await Promise.all([
        fetch(url1).then(r => r.json()),
        fetch(url2).then(r => r.json())
    ]);

    return {...data, result1.usefulData, result2.usefulData};
}

Or, I often use a helper function in my code when doing a lot of fetch() calls:

function fetchJson(...args) {
    return fetch(...args).then(r => r.json());
}

async function fetchWeatherAPI() {
    //data that I need
    let data = {};

    const [result1, result2] = await Promise.all([
        fetchJson(url1),
        fetchJson(url2)
    ]);

    return { ...data, result1.usefulData, result2.usefulData };
}
  • Related