The FETCH API is a concept provided by native JavaScript to interact with Web servers. How do we use fetch in async and await? And how do you use it with TypeScript? Let’s explore…

Create a simple request

ES new supports await at the top level, so we just need to precede the fetch function with the await keyword

const response = await fetch("https://jsonplaceholder.typicode.com/todos");
Copy the code

To get the content of the response, we need to call the JSON method of Response

const body = await response.json();
Copy the code

Note: We use the await keyword because Response.json () is asynchronous.

Create a utility function

We create a request utility function that can be called, HTTP, that combines the above two lines and returns the response content

export async function http(request: RequestInfo) :Promise<any> {
  const response = await fetch(request);
  const body = await response.json();
  return body;
}

// example consuming code
const data = await http("https://jsonplaceholder.typicode.com/todos");
Copy the code

Great! By calling the request tool-HTTP function, we realized the data request and response in one line of code!

Define the type of response data

In the previous example, we set the type of the response data to Promise

, and let’s make this type more precise

export async function http<T> (request: RequestInfo) :Promise<T> {
  const response = await fetch(request);
  const body = await response.json();
  return body;
}

// example consuming code
interface Todo {
  userId: number;
  id: number;
  title: string;
  completed: boolean;
}

const data = await http<Todo[]>("https://jsonplaceholder.typicode.com/todos");
Copy the code

Now, our HTTP function accepts a generic parameter as the type of the response data.

Generics enable our scenario: a function can support multiple data types without specifying the data type in advance, but only at the time of use

In the above code, the actual type of our data is Todo[]

Better definition of response types

interface HttpResponse<T> extendsResponse { parsedBody? : T; }export async function http<T> (request: RequestInfo) :Promise<HttpResponse<T>> {
  const response: HttpResponse<T> = await fetch(request);
  response.parsedBody = await response.json();
  return response;
}

// example consuming code
const response = await http<Todo[]>(
  "https://jsonplaceholder.typicode.com/todos",);Copy the code

Therefore, we use extends to inherit the Response content parsed by the Response type in TS. Before the entire response is returned, we set the parsedBody property on the response. We now have the complete response in the code above.

Catch errors in the HTTP tool

Now, let’s optimize the HTTP function to handle the case of an error in an HTTP request. If the request fails, we can use the OK property in the Response object to determine

export async function http<T> (request: RequestInfo) :Promise<HttpResponse<T>> {
  const response: HttpResponse<T> = await fetch(request);

  try {
    // If there is no response, an error may be reported here
    response.parsedBody = await response.json();
  } catch (ex) {}

  if(! response.ok) {throw new Error(response.statusText);
  }
  return response;
}

/ / sample
let response: HttpResponse<Todo[]>;
try {
  response = await http<Todo[]>("https://jsonplaceholder.typicode.com/todosX");
  console.log("response", response);
} catch (response) {
  console.log("Error", response);
}
Copy the code

Using a try… Catch throws the error ❎ outside

Request method encapsulation in HTTP

How can we use HTTP methods other than GET by calling HTTP functions, as shown below

const response = await http<{
  id: number; } > (new Request("https://jsonplaceholder.typicode.com/posts", {
    method: "post".body: JSON.stringify({
      title: "my post".body: "some content",})}));Copy the code

We passed an inline type {ID: number} for the expected response body type, that is, we want the ID of the new post returned to us.

Also note that we must use json.stringify to convert the POST object to a string.

It’s a bit of a hassle, but we can make the user’s life easier by providing specific functionality for different HTTP methods:

export async function get<T> (
  path: string,
  args: RequestInit = { method: "get" }
) :Promise<HttpResponse<T>> {
  return await http<T>(new Request(path, args));
};

export async function post<T> (
  path: string,
  body: any,
  args: RequestInit = { method: "post", body: JSON.stringify(body) }
) :Promise<HttpResponse<T>>  {
  return await http<T>(new Request(path, args));
};

export async function put<T> (
  path: string,
  body: any,
  args: RequestInit = { method: "put", body: JSON.stringify(body) }
) :Promise<HttpResponse<T>> {
  return await http<T>(newRequest(path, args)); }; .// example consuming code
const response = await post<{ id: number} > ("https://jsonplaceholder.typicode.com/posts",
  { title: "my post".body: "some content"});Copy the code

Therefore, these functions call basic HTTP functions, but set the correct HTTP method and serialize the request body for us.

Now it’s even easier to use HTTP requests!

conclusion

With the help of some good packaging, we can easily fetch, await, async, TypeScript. We also throw HTTP request errors, which is arguably a more common behavior of HTTP libraries. Finally, it encapsulates functions for HTTP request methods, making it easy to interact with Web services.

Reference Documents:

  • www.carlrippon.com/fetch-with-…

The last

Of course! There are still many request process issues to be determined and resolved! We will update later, stay tuned!

What do you think the fetch tool above needs to be optimized for? Feel free to leave your thoughts in the comments!

Feel the harvest of friends welcome to praise, pay attention to a wave!

The articles

React Build series

  1. How to build the enterprise front-end development specification 🛠
  2. React Build integration Webpack5/React17
  3. React Build integrated CSS/Less/Sass/Antd
  4. React Build integrated image/font
  5. React Build integration with Redux/Typescript
  6. React Build uses redux-thunk to implement asynchronous Redux operations
  7. React Build integrates React-Router/Antd Menu to implement route permissions