TL; DR
Позвоните по коду, чтобы создать и обработать ваш chart
после , когда вы получили данные от вашего http.get
вызова.
Более длинная версия
TestVar
не определена, потому что вы пытаетесь использовать значение до того, как оно будет заполнено вашей функцией обратного вызова subscribe
.
Observable
с потоком данных асинхронно (не для путать с async
/ await
с обещаниями). Прочитайте Rx Js Документы , чтобы ознакомиться с тем, как они работают и как их использовать.
Ваш http.get
вызов возвращает данные после того, как вы уже создал и визуализировал график. В какое время при создании / рендеринге значение TestVar
по-прежнему равно undefined
, поскольку оно еще не установлено.
Вам необходимо установить TestVar
значение внутри обратный вызов и , затем используйте код, который вы используете для настройки и визуализации диаграммы, например:
TestVar: string;
constructor(private readonly _http: HttpClient) { }
ngOnInit() {
this._http.get<DataModel>('./assets/data.json')
.subscribe(data => {
this.TestVar = data[0].District;
// code to render chart AFTER you've retrieved the value
});
}
Обратите внимание, что вам не нужно создавать и назначать cities
переменная класса Observable<DataModel>
, так как вы используете ее только локально и нигде больше, и вместо этого можете «связать» вызов с возвращенным Observable
, чтобы подписаться на нее.
Обратите внимание, что это желательно создавать и подписываться на вещи внутри ngOnInit()
, а не в конструкторе. ngOnInit
ловушка жизненного цикла указывает, что Angular создал компонент, и все привязки готовы, поэтому вы не создаете все вещи внутри него, прежде чем Angular сможет что-либо отобразить. Вот гораздо лучшее объяснение на SO о различиях между constructor
и ngOnInit
.
Еще лучше:
Вы используете только TestVar
значение один раз / локально, поэтому я не вижу необходимости устанавливать его как переменную класса (как с переменной класса cities
).
Вместо этого просто возьмите значение и используйте его внутри Ваш обратный вызов:
// no need for the TestVar inside the class
constructor(private readonly _http: HttpClient) { }
ngOnInit() {
this._http.get<DataModel>('./assets/data.json')
.subscribe(data => {
const district = data[0].District;
// use the district variable when setting up your chart
});
}
Еще лучше:
Извлеките код создания диаграммы в свою собственную функцию внутри вашего класса, которая принимает значение District
в качестве ввода, чтобы ваш код был красивым и чистым, вместо того, чтобы иметь большую длинную функцию ngOnInit()
.
Это сделает ваш код намного более читабельным и будет легче видеть, что происходит:
ngOnInit() {
this._http.get<DataModel>('./assets/data.json')
.subscribe(data => {
const district = data[0].District;
// then set up the chart
this.initializeChart(district);
});
}
private initializeChart(district: string) {
// your code to initialize chart, using the district param passed in
}