Type 'Observable<ArrayBuffer>' is not assignable to type 'Observable<Date[]>'

Viewed 1044
  consultar ( opcion: string, articulo: Articulo ): Observable<Date[]> {
    return this.http.get<Date[]>( this.rootUrl + "consultar?opcion=" + opcion, articulo );
  }

PROBLEM: Type 'Observable' is not assignable to type 'Observable<Date[]>'. Type 'ArrayBuffer' is missing the following properties from type 'Date[]': length, pop, push, concat, and 27 more.

2 Answers

The second parameter in get should be options, but you are probably passing it data.

Angular docs - get method

Constructs a GET request that interprets the body as an ArrayBuffer and returns the response in an ArrayBuffer.

Get Method Parameters

Since the accepted Suggested edit queue is full right now - 2022-06-25 - I decided to write this answer which contains more details and example to elaborate and illuminate the problem:

Elaborating the problem

I had an interface:

export interface Media {
  id?: number;
  name: string;
  medium: string;
  category: string | null;
  year: string | null;
  watchedOn: string | null;
  isFavorite: boolean | null;
}

And a service layer which was responsible to perform http calls:

@Injectable({
  providedIn: 'root',
})
export class MediaService {
  private readonly baseUrl: string;

  constructor(private httpClient: HttpClient) {
    this.baseUrl = environment.baseUrl.concat('/medias');
  }

  get(filters: Partial<Media>): Observable<Media[]> {
    return this.httpClient
      .get<Media[]>(this.baseUrl, {
        params: { ...filters },
      })
      .pipe(
        map((media) => {
          // TODO: Do required normalization
          return media;
        }),
      );
  }
}

When we are doing something like this Angular think we wanna use this overload:

get(url: string, options: {
    headers?: HttpHeaders | {
        [header: string]: string | string[];
    };
    context?: HttpContext;
    observe?: 'body';
    params?: HttpParams | {
        [param: string]: string | number | boolean | ReadonlyArray<string | number | boolean>;
    };
    reportProgress?: boolean;
    responseType: 'arraybuffer';
    withCredentials?: boolean;
}): Observable<ArrayBuffer>;

While we do not.

Solution

The problem rises from those | null which we have in our interface. We need to somehow guarantee that we won't pass null value to the http param. JSON can just do that, So in the service layer I change the get method just like this:

get(filters: Partial<Media>): Observable<Media[]> {
  // All the magic happens in these two line:
  const illuminateNils = JSON.parse(JSON.stringify(filters));
  const params = new HttpParams({
    fromObject: illuminateNils,
  });

  return this.httpClient
    .get<Media[]>(this.baseUrl, {
      params,
    })
    .pipe(
      map((media) => {
        // TODO: Do required normalization
        return media;
      }),
    );
}

And now Typescript is not hysterical. And our code is more secure and understandable thanks to picky Typescript.

Related