My Fetch Wrapper with async/await and TypeScript

avxkim

Alexander Kim

Posted on February 13, 2020

My Fetch Wrapper with async/await and TypeScript

Posting my wrapper for a native fetch() API:

const API_URL: string = process.env.YOUR_ENV_NAME || 'https://example.com';

export default async <T, B>(
  url: string,
  method = 'get',
  body: B | undefined = undefined,
  headers = {}
): Promise<T | { error: string }> => {
  const controller = new AbortController();
  try {
    const res = await fetch(`${API_URL}${url}`, {
      method: method.toUpperCase(),
      signal: controller.signal,
      body: typeof body === 'object' ? JSON.stringify(body) : undefined,
      mode: 'cors',
      headers: {
        'Content-type': 'application/json',
        ...headers
      }
    });
    if (!res.ok) {
      const error = await res.json();
      return { error: error.code };
    }
    return await res.json();
  } catch (err) {
    return { error: err };
  } finally {
    controller.abort();
  }
};

Enter fullscreen mode Exit fullscreen mode

And we can use it this way:

const result = await api<IResponse, IBody>('url', 'post', { name: 'asd' });
if (result.error) {
  // handle error;
} else {
  // handle successful response
}
Enter fullscreen mode Exit fullscreen mode

We can type our response as 1st type argument, and body as 2nd.

I wrote it to use in my React app. Improvements of this code snippet are welcome!

💖 💪 🙅 🚩
avxkim
Alexander Kim

Posted on February 13, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related