Reputation:
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
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
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
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
Reputation: 2582
You should use (containers: any[]) when declaring the var:
ngOnInit() {
this.docker.getContainers().subscribe((containers: any[]) => {
console.log(containers.length);
});
}
Upvotes: 12
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
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