Angular2(Typescript) Http wrapper with RxJS observables and generic types

Today I faced a challenge while working on an abstract http service implementation. The goal of this service is to serve as a base for extending all other http services.

Here's the current implementation, excluding some methods for illustration:

@Injectable()
export abstract class HttpWrapper<T> {

  private options: RequestOptions;

  constructor(private http: Http, private endpointUrl: string) {
    let headers = new Headers();
    headers.append('Content-Type', 'application/json');
    this.options = new RequestOptions({ headers: headers });
  }

  public getAll(): Observable<T[]>{
    return this.http.get(this.endpointUrl, this.options)
      .map(this.extractAll)
      .catch(this.handleError);
  }

  abstract handleError(error: any):Observable<Response>;

  abstract extractOne(res: Response):T;

  abstract extractAll(res: Response):T[];
}

When attempting to use the abstract HttpWrapper, I proceed as follows:

@Injectable()
export class BlastReportService extends  HttpWrapper<Item> {

  constructor(http: Http) {
    super(http,'/api/items');
  }


  handleError(error: any):Observable<Response>{
    //Handling error
    return Observable.throw(error);
  }

  extractAll(res: Response):Item[]{
    let body = res.json();

    let formattedBody = body.map((item: Item) => {
      item = new Item(item);
      return blastReport;
    });

    return formattedBody || [{}];
  }
}

However, this leads to a compilation error:

Type 'Observable<Response>' is not assignable to type 'Observable<T[]>'.
  Type 'Response' is not assignable to type 'T[]'.
    Property 'find' is missing in type 'Response'.

This error is baffling because the method extractAll clearly returns Item[] and is utilized when mapping the results obtained from the server.

I decided to implement this abstract HttpWrapper approach to maintain DRY principles. Although I'm unsure if it's the most effective strategy.

Answer №1

It seems that the issue arises from the fact that handleError() is returning an Observable<Reponse>, which does not align with the expected return type of getAll() that requires an Observable<T[]>

To resolve this problem, you should adjust the return type of handleError to Observable<T[]>.

Within HttpWrapper

abstract handleError(error: any): Observable<T[]>

Inside BlastReportService

handleError(error: any): Observable<T[]> {
  return Observable.throw(error)
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Pagination of the Angular Material table connected to a GraphQL server

Looking to implement pagination on an Angular Material table, but facing a challenge with the data response coming from a GraphQL backend. The structure of the data is as follows: import { Component, OnInit, ViewChild } from '@angular/core'; impo ...

Guide on how to execute the `require("express");` command within a TypeScript Angular Component in an Electron Application

Recently, I ventured into learning about "Angular", "typescript", and "Electron". To kickstart my project, I managed to create a file named "server.js" using the starter example from express. However, I am unsure of the correct method to set up a local ser ...

Angular - calculate the total of numerical values within a nested *ngFor loop

Looking to extract numerical values from an array of objects, where each object contains specific data within arrays. I attempted using *ngFor to iterate through the values, but instead of summing them up, they are concatenated together. Here's a brie ...

Encountered a bug in the findUnique function within the services of a Nest JS and Prisma project

I have a question about using Prisma with Nest. I keep encountering this error: src/modules/auth/auth.service.ts:28:63 - error TS2322: Type 'UserWhereUniqueInput' is not assignable to type 'string'. 28 const user = await this.prisma ...

Transferring data types to a component and then sending it to a factory

I have been grappling with creating a factory method using Angular 2 and TypeScript. However, my attempts have hit a roadblock as the TSC compiler keeps throwing an unexpected error: error TS1005: ',' expected. The issue arises when I try to pa ...

Angular unable to retrieve data using Angularfire2

Having trouble retrieving data from the Real time Database on firebase. Read and Write permissions are set to public so no authentication is needed. The npm compilation is successful, indicating that the Angular-CLI code is correct. Following the document ...

Exploring SubjectBehavior within my UserService and Profile Component

Within my ShareService, I have the following code snippet: isLogin$:BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false); <==== default value is false CheckUser = this.isLogin$.asObservable(); public isLogin (bool){ ...

Incorporating Angular views as peer components within the current view

I am currently working on implementing this HTML structure: <tr *ngFor="let row of rows"> <expandable-tree-row [columns]="cols" [data]="row"></expandable-tree-row> </tr> Within the ExpandableTreeRo ...

Dependency error reported in Angular update

Encountering an issue with updating my angular project - when running ng update @angular/core, I receive the following error message: Using package manager: 'npm' Collecting installed dependencies... Found 41 dependencies. Fetching dependency met ...

Is there a way to make Firebase Cloud Functions utilize ESLint?

Is there a specific command to activate ESLint for my cloud functions? Just to provide some context, I executed firebase init and completed the setup process, but it ended up using ESLint instead of TSLint which was unexpected. After that, I ran firebase ...

What is the best way to showcase a variable from a typescript file in an HTML file with Angular?

In my TypeScript file, I have the following function: ngOnInit() { if (sessionStorage['loyalPage']) { this.page = Number(sessionStorage['loyalPage']); } this.webService.getLoyalPlayers(this.pag ...

Button to expand or collapse all sections in Ant Design Collapse component

Is there a way to create a button that can expand or collapse all tabs in an ant.design Collapse component? I attempted to modify defaultActiveKey but it seems like this can only be done during page rendering. If possible, could someone share a code snip ...

Using TypeScript in the current class, transform a class member into a string

When converting a class member name to a string, I rely on the following function. However, in the example provided, we consistently need to specify the name of the Current Component. Is there a way to adjust the export function so that it always refers ...

Receiving real-time updates on all devices from the server

Utilizing Angular 2, I have set up a system to send requests to my Laravel PHP API and display the results on my client. To continuously receive updates from the server and refresh my data, I have implemented the following code snippet which calls the API ...

Angular 2: How to Avoid Exceeding Maximum Call Stack Size with Eager Loading

I'm facing an issue with preloading all of my child route modules. In my root routing module, I have the following configuration: RouterModule.forRoot(appRoutes, { preloadingStrategy: AppCustomPreloader }) The structure of AppCustomPreloader is as f ...

What steps can be taken to safeguard data while navigating within the Angular framework?

I am facing an issue with storing an array of items in a service (referred to as cart service) and displaying it in the component (cart.component.ts). The components bgview.component.ts and single.component.ts are involved in selecting individual items, wi ...

Issue arising with data exchange between components using data service in Angular 5

Utilizing data service to share information between components has presented a challenge for me. References: Angular: Updating UI from child component to parent component Methods for Sharing Data Between Angular Components Despite attempting the logic o ...

Adding a custom role in Angular TypeScript in Microsoft AppInsights is a straightforward process that can provide valuable

I have an angular project where I am looking to incorporate AppInsight with custom telemetry (role). The project is built in Angular using TypeScript, and I successfully integrated appinsights by following this tutorial. However, when attempting to add cus ...

Repetitive cycling through an array

My array consists of classes: const transferClasses = [ { id: "c5d91430-aaab-ed11-8daf-85953743f5cc", name: "Class1", isTransfer: false, children: [], }, { id: "775cb75d-aaab-ed11-8daf-85953743f5cc", ...

What is the most effective method for delivering a Promise after an asynchronous request?

Currently, I am working on creating an asynchronous function in TypeScript that utilizes axios to make an HTTP request and then returns a Promise for the requested data. export async function loadSingleArweaveAbstraction(absId : string) : Promise<Abstra ...