Protagonist
Protagonist

Reputation: 1669

type observable<{}> is not assignable to any type:Property length is missing in type{} in Typescript

I'm trying to get JSON data kept in the local system using Angular2 http.

import { Injectable }     from '@angular/core';
import { Http, Response } from '@angular/http';
import { General }        from './general';
import { Observable }     from 'rxjs/Observable';

@Injectable()
export class GeneralService {
    // #docregion endpoint
    private statusUrl = './jsondata';  // URL to web API
    // #enddocregion endpoint

    // #docregion ctor
    constructor (private http: Http) {}
    // #enddocregion ctor

    // #docregion methods, error-handling, http-get
    getStatus (): Observable<General[]> {
        return this.http.get(this.statusUrl)
            .map(this.extractData)
            .catch(this.handleError);
    }
 private extractData(res: Response) {
        let body = res.json();
        return body.data || { };
    }


    private handleError (error: Response | any) {
        // In a real world app, we might use a remote logging infrastructure
        let errMsg: string;
        if (error instanceof Response) {
            const body = error.json() || '';
            const err = body.error || JSON.stringify(body);
            errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
        } else {
            errMsg = error.message ? error.message : error.toString();
        }
        console.error(errMsg);
        return Observable.throw(errMsg);
    }

}

I'm getting error- Type observable<{}> is not assignable to type 'Observable'.Type '{}' is not assignable to type 'General[]'. Property length is missing in type'{}'

Here General is a class name. Im using rxjs-5.0. I'm following Angular.io Tour of heroes and making my own project. Any help on this?

Upvotes: 11

Views: 23346

Answers (6)

Norman Pilusa
Norman Pilusa

Reputation: 337

I changed my imports from
import { Observable } from 'rxjs/Observable';
to
import { Observable } from 'rxjs';
And it all worked

Upvotes: 6

Swanand Taware
Swanand Taware

Reputation: 753

Update your code as below:

getStatus(): Observable<Genral[]> {
  return this.http.get(this.statusUrl)
    .map((res) => this.extractData(res))
    .catch((err) => this.handleError(err));
}

Upvotes: 0

jls2933
jls2933

Reputation: 11

The bad assign is not coming from the extractData() call but from the catch() one.

Try this:

getStatus(): Observable<General[]> {
    return this.http.get(this.statusUrl)
        .map(this.extractData)
        .catch<General[]>(this.handleError);
}

Upvotes: 0

Jorawar Singh
Jorawar Singh

Reputation: 7621

The problem is that you are telling to observable to get a list of Genral while you are getting an object.

getStatus (): Observable<General[]>

If you are not accepting an array then you should do like this

getStatus (): Observable<General> 

Upvotes: 4

Radim K&#246;hler
Radim K&#246;hler

Reputation: 123901

I would adjust the extractData like this:

private extractData(res: Response): General[] {
    let body = res.json();
    return (body.data || []) as General[];
}

Now it says that it will return General[] and also it asserts the body.data to be of that type. In case, of null result, empty array is returned

Upvotes: 1

Alex
Alex

Reputation: 14523

The compiler say that you try to assign an object to an array (of Generals).

I guess that your problem is in return body.data || {} in extractData. Try return body.data || [] instead.

Upvotes: 0

Related Questions