Инициализация свойств внутри области действия ngOnInit - PullRequest
0 голосов
/ 28 мая 2019

Я использую ngOnInit для получения ответа от вызова Loopback API. Свойство, которое я инициализирую внутри этой области, не может использоваться вне области подписки. Я знаю, что это простой ответ, но я просто не вижу его

private siteData: Kiosk;

  constructor(private dataService: DataService){} 

 ngOnInit(){
    this.dataService.getDataByID(this.dataService.getSiteID())
        .subscribe((data:Site) => { 
             this.siteData = data;
             console.log(this.siteData); // This outputs correctly 
    });
    console.log(this.siteData); // This is undefined
  }

  site: any[] = [{
    title: this.siteData.title, // this is undefined and throws error
  }];

Я ожидаю, что выходные данные не будут неопределенными и будут данными в ответе

Ответы [ 5 ]

1 голос
/ 28 мая 2019

Я также хочу показать вам, как лучше понять хуки жизненного цикла в Angular. Вы устанавливаете свойство класса следующим образом:

site: any[] = [{
    title: this.siteData.title, // this is undefined and throws error
  }];

Это означает, что вы обращаетесь к this.sideData, который устанавливается только в хуке ngOnInit, который фактически запускается после инициализации (создания) компонента. Кроме того, вы подписываетесь только на Observable в ловушке жизненного цикла (OnInit), т. Е. Вы еще не активно присваиваете результат, только после того, как наблюдаемое выдает результат. Ваша наблюдаемая не обязательно должна быть асинхронной, но в вашем случае она, скорее всего, равна.

Короткая история: вы получаете ошибки, потому что вы пытаетесь получить доступ к свойству объекта this.siteData, который на данный момент не определен.

1 голос
/ 28 мая 2019

Это потому, что наблюдаемые являются асинхронными.sideData не определяется до тех пор, пока в вызове subscribe не выполнено присвоение - оно похоже на обещание.

Если вы попытаетесь получить доступ к значению, установленному обещанием, до вызова .then, тоэто также будет неопределенным.Обойти это можно было бы с помощью оператора tap, чтобы установить его в конвейер, а затем использовать его другими способами в подписке.В качестве альтернативы вы можете использовать что-то вроде ngrx, которое будет автоматически обновлять до последнего значения.

0 голосов
/ 28 мая 2019

заполните свои поля только тогда, когда вы получите такие данные:

private siteData: Kiosk;
site: any[];

  constructor(private dataService: DataService){} 

 ngOnInit(){
    this.dataService.getDataByID(this.dataService.getSiteID())
        .subscribe((data:Site) => { 
             this.siteData = data;
             site = [{title: data.title}];
    });
  }
0 голосов
/ 28 мая 2019

Вам нужно будет инициализировать переменные внутри метода подписки значениями, которые вы уже делаете.

Теперь вы можете получить к ним доступ в HTML после завершения запроса. Обязательно добавьте проверку в HTML, т.е. если siteData с использованием *ngIf, а затем используйте эти переменные обычно

0 голосов
/ 28 мая 2019
console.log(this.siteData); // This is undefined

, потому что это не ждет, пока this.dataService.getDataByID завершит использование того, что внутри, если вы не хотите, чтобы оно было неопределенным

...