Skip to content

Instantly share code, notes, and snippets.

@MuhammadKhizar7
Last active April 29, 2021 01:21
Show Gist options
  • Save MuhammadKhizar7/dbbba3d44e8cca1c9a179eb2dd68a451 to your computer and use it in GitHub Desktop.
Save MuhammadKhizar7/dbbba3d44e8cca1c9a179eb2dd68a451 to your computer and use it in GitHub Desktop.
gistpad-scratch

Fatch Api Solution

/*
 Parses the JSON returned by a network request
 @param {object} response A response from a network request
 @return {object} The parsed JSON, status from the response
 */
    function parseJSON(response) {
      return new Promise((resolve) => response.json()
      .then((json) => resolve({
      status: response.status,
      ok: response.ok,
      json,
      })));
      }
/*
 Requests a URL, returning a promise
 @param {string} url The URL we want to request
 @param {object} [options] The options we want to pass to "fetch"
 @return {Promise} The request promise
 */
    export default function request(url, options) {
      return new Promise((resolve, reject) => {
        fetch(endpoint  + url, options)
          .then(parseJSON)
          .then((response) => {
            if (response.ok) {
              return resolve(response.json);
            }
            // extract the error from the server's json
            return reject(response.json.meta.error);
          })
          .catch((error) => reject({
            networkError: error.message,
          }));
      });
    }

For me, fny answers really got it all. since fetch is not throwing error, we need to throw/handle the error ourselves. Posting my solution with async/await. I think it's more strait forward and readable

Solution 1: Not throwing an error, handle the error ourselves

  async _fetch(request) {
    const fetchResult = await fetch(request); //Making the req
    const result = await fetchResult.json(); // parsing the response

    if (fetchResult.ok) {
      return result; // return success object
    }


    const responseError = {
      type: 'Error',
      message: result.message || 'Something went wrong',
      data: result.data || '',
      code: result.code || '',
    };

    const error = new Error();
    error.info = responseError;

    return (error);
  }

Here if we getting an error, we are building an error object, plain JS object and returning it, the con is that we need to handle it outside. How to use:

  const userSaved = await apiCall(data); // calling fetch
  if (userSaved instanceof Error) {
    debug.log('Failed saving user', userSaved); // handle error

    return;
  }
  debug.log('Success saving user', userSaved); // handle success
Solution 2: Throwing an error, using try/catch

async _fetch(request) {
    const fetchResult = await fetch(request);
    const result = await fetchResult.json();

    if (fetchResult.ok) {
      return result;
    }

    const responseError = {
      type: 'Error',
      message: result.message || 'Something went wrong',
      data: result.data || '',
      code: result.code || '',
    };

    let error = new Error();
    error = { ...error, ...responseError };
    throw (error);
  }

Here we are throwing and error that we created, since Error ctor approve only string, Im creating the plain Error js object, and the use will be:

  try {
    const userSaved = await apiCall(data); // calling fetch
    debug.log('Success saving user', userSaved); // handle success
  } catch (e) {
    debug.log('Failed saving user', userSaved); // handle error
  }
Solution 3: Using customer error

  async _fetch(request) {
    const fetchResult = await fetch(request);
    const result = await fetchResult.json();

    if (fetchResult.ok) {
      return result;
    }

    throw new ClassError(result.message, result.data, result.code);
  }

And:

class ClassError extends Error {

  constructor(message = 'Something went wrong', data = '', code = '') {
    super();
    this.message = message;
    this.data = data;
    this.code = code;
  }

}


function makeRequest(url, options) {
    return new Promise((resolve, reject) => {
        fetch(url, options)
            .then(handleResponse)
            .then(response => JSON.parse(response))
            .then((json) => resolve(json))
            .catch((error) => {
                try {
                    reject(JSON.parse(error))
                }
                    catch(e) {
                        reject(error)
                    }
            })
    })
}

function handleResponse(response) {
    return response.json()
        .then((json) => {
            // Modify response to include status ok, success, and status text
            let modifiedJson = {
                success: response.ok,
                status: response.status,
                statusText: response.statusText ? response.statusText : json.error || '',
                response: json
            }

            // If request failed, reject and return modified json string as error
            if (! modifiedJson.success) return Promise.reject(JSON.stringify(modifiedJson))

            // If successful, continue by returning modified json string
            return JSON.stringify(modifiedJson)
        })
}



// Then I use it in other files like so. First declare any options, if needed.

const options = {
// your options... method: POST, headers, cors, etc.
}

// Then make the request using the promise function
makeRequest(/oauth/token, options)
            .then((data) => console.log(data)) // do something great with data
            .catch(error => console.log(error)) // do something useful with error



function handleErrors(response) {
    if (!response.ok) {
        throw Error(response.statusText);
    }
    return response;
}
fetch("http://httpstat.us/500")
    .then(handleErrors)
    .then(response => console.log("ok") )
    .catch(error => console.log(error) );


const fetchUsers = async () => {
    try {
        const res = await fetch('https://reqres.in/api/users');
        if (!res.ok) {
            throw new Error(res.status);
        }
        const data = await res.json();
        console.log(data);
    } catch (error) {
        console.log(error);
    }
}

fetchUsers();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment