Search code examples
reactjstypescriptfetchresponsehttpservice

ReactJS how do I retrieve response.status in component?


I have a Login-Component, where I call my LoginService:

const result = await this.context.loginService.login({
    username: this.state.password!,
    password: this.state.password!,
  });

In this result, I want my Status-Codes of the HTTP-Response.

The login()-Method looks like this:

public async login(credentials: Credentials) {
return firstValueFrom(
  from(
    this.httpService.fetch<{ jwt: string }>(
      `${this.apiUrl}employees/login`,
      HttpMethod.POST,
      {
        username: btoa(credentials.username),
        password: btoa(credentials.password),
      }
    )
  ).pipe(
    switchMap((result) =>
      result?.jwt ? this.authService.saveToken(result.jwt) : of(null)
    ),
    switchMap((token) =>
      token ? this.authService.getToken(true) : of(null)
    ),
    map((decoded) => decoded?.userid || null),
    first(),
    catchError(() => of(null))
  )
)
}

Which is there accessing the fetch()-Method of my HttpService:

public async fetch<T>(
url: string,
method: HttpMethod,
body?: Record<string, unknown> | Array<Record<string, unknown>>,
header?: Record<string, unknown>,
responseTypeJson = true
  ): Promise<T> {
    const token = await lastValueFrom(
      this.authService.getToken(false).pipe(first())
    );
    const authHeader = token ? { Authorization: `Bearer ${token}` } : undefined;
    const headers = {
      ...(method !== HttpMethod.GET
        ? { "Content-Type": "application/json" }
        : undefined),
      ...authHeader,
      ...header,
    };
    const response = await fetch(url, {
      method,
      headers,
      body: JSON.stringify(body),
    });
    return responseTypeJson && response ? ((await response.json().catch(() => response)) as T) : (response as T);
  }

I've seen posts like this, but I don't know how to manipulate the response in my HttpService and make it return a response in type of Response. Additionally, this is the code of my colleague, whom I can't contact right now, so I hope, you guys can help me through his code. :D


Solution

  • const response = await fetch(url, {
              method,
              headers,
              body: JSON.stringify(body),
            });
    
    // here you have access to the response status
    if(response.status === 400){
    ...
    }
    
    return responseTypeJson && response ? ((await response.json().catch(() => response)) as T) : (response as T);
    

    if you return response.json() you are extracting only the body of the response. If you want to handle the response somewhere else just return response.

    Also keep in mind that fetch doesn't throw error if the response status is between 400 and 600, if you want to throw an error (and catch it) you have to check and throw manually.