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.

share|improve this question
    
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. – JB Nizet Aug 19 at 7:21
    
Also, your method is supposed to return an Observable<T[]>, but handleError returns an Observable<Response>. – JB Nizet Aug 19 at 7:27
    
Sorry about that blastReport, that shouldn't be in the question. Editing that. – Mike Spencer Aug 19 at 7:31
up vote 0 down vote accepted

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)
}
share|improve this answer
    
Hi Philippe Plantier, the issue was in deed in handleError return value. Thank you very much. – Mike Spencer Aug 19 at 17:07
    
Honestly I feel bit ashamed to post such a stupid question. – Mike Spencer Aug 19 at 17:09

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.