mnlfischer mnlfischer - 9 days ago 5
TypeScript Question

class variable is undefined after subscribing observable in lifecycle hook

I try to set a variable (json object) in my component class. ngOnInit subscribing an observable service and set the component variable.
When I try to access this variable with dot notation in components template, I get this error:


Cannot read property 'count_runs' of undefined


The observable has a type annotation (avgTime Interface).

avg-time.ts

export interface AvgTime {
avg_runtime_millis: number;
count_runs: number;
}


stats.service.ts

import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { AvgTime } from './avg-time';
import { Observable } from 'rxjs/Observable';

@Injectable()
export class StatsService {
constructor(private _http: Http) { }

private _avgTimeUrl = 'http://localhost:3002/api/reservation/avgTime';

getAvgTime() : Observable<AvgTime> {
return this._http.get(this._avgTimeUrl)
.map(res => res.json());
}
}


avg-time.component.ts

import {Component, OnInit} from '@angular/core';
import { AvgTime } from './avg-time';
import { StatsService } from './stats.service';

@Component({
selector: 'avg-time',
template: `
<h1>AvgTimeComponent</h1>
{{avgTime.count_runs}}
`,
providers: [StatsService]
})
export class AvgTimeComponent implements OnInit {
avgTime: AvgTime;

constructor(private _statsService: StatsService) { }

ngOnInit() {
this._statsService.getAvgTime()
.subscribe(avgTime => this.avgTime = avgTime);
}
}


It is also not working when I fake the service response in ngOnInit like:

avg-time.component.ts

ngOnInit() {
this._statsService.getAvgTime()
.subscribe(avgTime => {
this.avgTime = {
avg_runtime_millis: 150,
count_runs: 20
};
});
}


The return of my stats.service.ts from backend is:

[{"AVG_RUNTIME_MILLIS":55,"COUNT_RUNS":5400}]

Answer

You need to leverage the Elvis operator:

{{avgTime?.count_runs}}

since avgTime is set asynchronously and is undefined at first...

Comments