How do I use angular http.post and change Type 'Observavble<unknown> to a typed response?

42 Views Asked by At

I keep getting confused about how to type my HttpResponse. I'm trying to match what my api is giving me back but my typescript help in vim keeps telling me:

typescript: Type 'Observable<unknown>' is not assignable to type 'Observable<string | HttpErrorResponse>'.
  Type 'unknown' is not assignable to type 'string | HttpErrorResponse'. [2322]

This is what my post looks like:

forgotPassword(args: {studentId: string, emailAddress: string}): RxObservable<HttpErrorResponse | string> {
  const body = {
    studentId: args.studentId,
    emailAddress: args.emailAddress
  }
    console.log("forgot password", body)

    return this.http
      .post<HttpErrorResponse | string>(
        `${this.nextApiEndpoint}Authentication/ForgotPassword`,
        body,
        {}
      )
      .pipe(
        switchMap((data: string) => data),
        catchError((err) => {
          return err;
        })
      );
  }

I'm trying to use switchMap to make sure the data piped out is string, but I really don't need that because that is what my http response is already, a string.

1

There are 1 best solutions below

2
Naren Murali On BEST ANSWER

You can just remove the HttpErrorResponse from the post and let catchError contain the type HttpErrorResponse. Also since we are not calling another API call with the previous data I swapped the switchMap with a map.

To sum it up, we don't need to add extra lines for HttpErrorResponse just the success return type is enough and typescript will allow this.

import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable, of } from 'rxjs';
import { catchError, map } from 'rxjs/operators';

@Injectable()
export class TestService {
  nextApiEndpoint = 'google.com';
  constructor(private http: HttpClient) {}

  forgotPassword(args: {
    studentId: string;
    emailAddress: string;
  }): Observable<string> {
    const body = {
      studentId: args.studentId,
      emailAddress: args.emailAddress,
    };
    console.log('forgot password', body);

    return this.http
      .post<string>(
        `${this.nextApiEndpoint}Authentication/ForgotPassword`,
        body,
        {}
      )
      .pipe(
        catchError((err: HttpErrorResponse) => {
          throw 'error in source. Details: ' + err.message;
        }),
        map((data: string): string => data)
      );
  }
}

Stackblitz Demo with no compilation errors