Angular: переменная не обновляется после подписки - PullRequest
0 голосов
/ 27 мая 2020

У меня есть служба, которая возвращает Observables<SubscriberModel[]>.

export interface SubscriberModel {
    email: string;
}

в моем компоненте. Я получаю подписчиков $ в конструкторе:

public subscribers$: Observable<SubscriberModel[]>;
this.subscribers$ = this.subscribersService.getAll();

и показываю их в шаблоне:

<p *ngFor="let subscriber of subscribers$ | async">{{subscriber.email}}</p>
<button (click)="onDownloadClick()">
    <a [href]="fileUrl" download="file.txt">DownloadFile</a>
</button>

Мне нужно загрузить моих подписчиков в файл:

public data: any;

public onDownloadClick(): void {
    this.subscribers$.pipe(
        map(res => res.map(i => i.email)),
    )
        .subscribe(res => {
            console.log(res) //array of string
            this.data = res;
        });

    console.log(this.data); //undefined
    const blob: Blob =
        new Blob([this.data], {type: 'application/octet-stream'});

    this.fileUrl =
        this.sanitizer.bypassSecurityTrustResourceUrl(window.URL.createObjectURL(blob));
}

Почему в console.log this.data не определено?

Ответы [ 2 ]

3 голосов
/ 27 мая 2020

поместите подписку на свою службу, связанную с процессами. Функции asyn c не останавливают другой процесс. Таким образом, код переходит к следующей строке, пока выполняется. поэтому вне asyn c функция может не читать данные из-за ответа сервера.

public onDownloadClick(): void {
   this.subscribers$.pipe( map(res => res.map(i => i.email)),)
   .subscribe(res => {
       console.log(res) //array of string
       this.data = res;
       console.log(this.data); //undefined
       const blob: Blob = new Blob([res], {type: 'application/octet-stream'});       
       this.fileUrl = this.sanitizer.bypassSecurityTrustResourceUrl(window.URL.createObjectURL(blob));
    });

}
1 голос
/ 27 мая 2020

this.data данные назначаются асинхронно. Таким образом, все зависимые операторы должны находиться внутри подписки. Таким образом, console.log должен находиться внутри подписки

public data: any;

public onDownloadClick(): void {
  this.subscribers$.pipe(
    map(res => res.map(i => i.email)),
  )
  .subscribe(res => {
    console.log(res) //array of string
    this.data = res;
    console.log(this.data);
    const blob: Blob = new Blob([this.data], {type: 'application/octet-stream'});
    this.fileUrl = this.sanitizer.bypassSecurityTrustResourceUrl(window.URL.createObjectURL(blob));
  });
}

Подробнее о доступе к асинхронным данным: { ссылка }

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...