user9793665
user9793665

Reputation:

property length does not exist on type Object

I have a services that get's a JSON from docker. I want to get the amount of containers.

So I subscribe to my service:

ngOnInit() {
    this.docker.getContainers().subscribe(containers => {
        console.log(containers.length);
    });
}

I get the right answer on the console and yet I get:

property length does not exist on type Object

Am I doing something wrong?

export class DockerService {
  private baseUrl:string = 'http://localhost:8080/api/docker';
  private headers = new HttpHeaders({'Content-Type':'application/json'});
  private options = new HttpHeaderResponse({headers:this.headers});

  constructor(private _http:HttpClient) { }

  getContainers() {
    return this._http.get(this.baseUrl + "/containers", this.options);
  }

  getImages() {
    return this._http.get(this.baseUrl + "/images", this.options);
  }
}

Upvotes: 7

Views: 28556

Answers (6)

Kartik Dolas
Kartik Dolas

Reputation: 761

Object does not have property like length but object has key value pair and there will be finite keys in an object so we can invoke length property on keys of object. I tried the following way and it worked for me.

ngOnInit() {
    this.docker.getContainers().subscribe((containers: any[]) => {
        console.log(Object.keys(containers).length);
    });
}

Upvotes: 0

MD Ashik
MD Ashik

Reputation: 9835

3/24/2019

Angular-7

I get Solution by using... Observable<any[]>

Example:

getContainers(): Observable<any[]> {
    return this._http.get<any[]>(this.baseUrl + "/containers", this.options);
}

Upvotes: 2

Azir Yasin
Azir Yasin

Reputation: 191

Since by default the HttpClient gets the response as an Object it does not have those properties. You can declare the containers as any[] and access the length property.

ngOnInit() {
this.docker.getContainers().subscribe(containers : any[] => {
    console.log(containers.length);
});
}

So change the code as above and it would work

Upvotes: 4

Ignacio Ara
Ignacio Ara

Reputation: 2582

You should use (containers: any[]) when declaring the var:

ngOnInit() {
    this.docker.getContainers().subscribe((containers: any[]) => {
        console.log(containers.length);
    });
}

Upvotes: 12

Benedikt Schmidt
Benedikt Schmidt

Reputation: 2278

Basically angular does not know which type is returned by your http call, therefore it autocasts it into an object, which has no length value. In order for it to work, you have to typecast it to what you are expecting it to be, in your example probably an array of Containers.

getContainers(): Container[] {
  return this._http.get<Container[]>(this.baseUrl + "/containers", this.options);
 }

This way angular will know what to expect and the attributes should exist. This of course depends on the Container class, which you probably don't have. Cleanest way would be to create this class and define its attributes to what is coming back from the backend.

However if for some reason you don't want to do this, you can probably just tell angular that you're expecting an array of any, which does not provide the type safety, but at least you'll have your length attribute.

getContainers(): any[] {
  return this._http.get<any[]>(this.baseUrl + "/containers", this.options);
 }

Upvotes: 3

Daniel Segura P&#233;rez
Daniel Segura P&#233;rez

Reputation: 1117

You should map your response, try this:

getContainers() {
    return this._http.get(this.baseUrl + "/containers", this.options).map(res => {
                return res.json();
            });
}



getImages() {
    return this._http.get(this.baseUrl + "/images", this.options).map(res => {
                return res.json();
            });
}

Upvotes: 0

Related Questions