1

Today I encountered the following problem while trying to implement an abstract http service. This service should be base to extend for all other http services.

The implementation is following so far, skipping other methods for ilustration:

@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[];
}

Now if i want to use the abstract HttpWrapper i do the following:

@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 formatedBody = body.map((item: Item) => {
      item = new Item(item);
      return blastReport;
    });

    return formatedBody || [{}];
  }
}

But doing this I get following 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'.

I can't wrap my head around this because the method extractAll clearly returns Item[] and is used while mapping the results returned from the server.

I decided to implement this abstract HttpWrapper "to stay DRY". I'm not sure if it's the best way to do so.

3
  • extractAll returns Item[], but your class is supposed to be a HttpWrapper<BlastReport>. So it's supposed to return a BlastReport[]. It's also unclear where this error message comes from. Please post the complete and exact error. Commented Aug 19, 2016 at 7:21
  • Also, your method is supposed to return an Observable<T[]>, but handleError returns an Observable<Response>. Commented Aug 19, 2016 at 7:27
  • Sorry about that blastReport, that shouldn't be in the question. Editing that. Commented Aug 19, 2016 at 7:31

1 Answer 1

2

It looks like the problem here is that handleError() returns an Observable<Reponse>, and therefore cannot be the return value of getAll() which expects an Observable<T[]>

Changing the return type of handleError to Observable<T[]> should fix the issue.

In HttpWrapper

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

In BlastReportService

handleError(error: any): Observable<T[]> {
  return Observable.throw(error)
}
Sign up to request clarification or add additional context in comments.

4 Comments

Hi Philippe Plantier, the issue was in deed in handleError return value. Thank you very much.
Honestly I feel bit ashamed to post such a stupid question.
T is not reconized in a Angular service do you have any ideas
You should create a new question for this problem, and post your code. But as a guess, I would say that your service is not generic ? typescriptlang.org/docs/handbook/generics.html#generic-classes

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.