Проблемы с GAPI и Angular 7

У меня есть запрос на Google диск с помощью gapi:

getFolders(folderId: string): Observable<{ id: string, name: string }[]> {
    const promise = gapi.client.drive.files.list({
      fields: 'incompleteSearch,nextPageToken,files(id,name)',
      q: `'${folderId}' in parents`,
    }).then((res) => {
      return JSON.parse(res.result.files);
    });
    return from(promise);
  }

затем я пытаюсь показать эти данные в компоненте: .ts файл ngOnInit:

this.data$ = this.googleDriveService.getFolders(rootFolderId)
        .pipe(
          map((files) => {
            debugger;
            return files.map(file => ({ id: file.id, header: file.name, content: '', imageUrl: this.defaultImageUrl }));
          }),
          takeUntil(this.destroy$),
        );

и html-файл:

  <mat-grid-tile *ngFor="let elem of (data$ | async)">
    <app-card (input)="returnCartItem(elem)" (click)="goto(elem.header, elem.id)"></app-card>
  </mat-grid-tile>

Проблема в том, что data$ всегда пусто. Я добавил debugger к map, чтобы проверить, может быть, что-то не так, но это никогда не входит в функцию map. Из ответа я получаю 2 файла, поэтому res.result.files не пусто;


person Dmytro Mysak    schedule 21.04.2019    source источник
comment
Вы имели в виду одинарные кавычки вокруг '${folderId}'?   -  person AryanJ-NYC    schedule 22.04.2019
comment
@AryanJ-NYC, к сожалению нет, проблема в том, что я отправляю запрос, получаю ответ (непустой), но он не отображается, потому что data$ - пустой   -  person Dmytro Mysak    schedule 22.04.2019
comment
Когда вы используете async pipe, вам не нужен takeUntil(this.destroy$), так как async pipe позаботится об отмене подписки за вас.   -  person frido    schedule 25.04.2019
comment
@fridoo спасибо за информацию   -  person Dmytro Mysak    schedule 06.05.2019


Ответы (4)


Проблема была в гапах (google API). Подробнее здесь Я создал частный метод inObservable

private inObservable(promise) {
    return from(
      new Promise((resolve, reject) => {
        this.zone.run(() => {
          promise.then(resolve, reject);
        });
      })
    );
  }

И заверните в него мою просьбу

const promise = gapi.client.drive.files.list({
      fields: 'incompleteSearch,nextPageToken,files(id,name)',
      q: `'${folderId}' in parents`,
    }).then((res) => {
      return JSON.parse(res.result.files);
    });
return inObservable(promise);
person Dmytro Mysak    schedule 06.05.2019

Вы превратили getFolders() в наблюдаемую, поэтому вам нужно подписаться на нее, чтобы начать получать от нее данные.

this.googleDriveService.getFolders(rootFolderId).pipe(...).subscribe();
person Paolo    schedule 21.04.2019
comment
Он использует канал async, который отвечает за подписку. - person AryanJ-NYC; 22.04.2019

Я думаю, что есть проблема в том, как используется асинхронность, попробуйте следующее:

<mat-grid-tile *ngFor="let elem of data$ | async">
    <app-card (input)="returnCartItem(elem)" (click)="goto(elem.header, elem.id)"></app-card>
</mat-grid-tile>
person Ritesh    schedule 22.04.2019
comment
Я добавил subscribe, но ничего не получил. Затем импортируйте private cdr: ChangeDetectorRef и запустите subscribe: this.cdr.detectChanges(); После этого углового перерисуйте мой компонент с данными. Итак, это мой временный обходной путь, но как это исправить, я понятия не имею - person Dmytro Mysak; 22.04.2019
comment
ts-файл: ghostbin.com/paste/j8wu6 html-файл: ghostbin.com/paste/mujx7 - person Dmytro Mysak; 22.04.2019
comment
Я использую google api и меняю файл app.module ts: ghostbin.com/paste/usqdj может что-то не так с ним? - person Dmytro Mysak; 22.04.2019
comment
Вы видите какие-либо ошибки в консоли? Как узнать, что сеанс Google установлен. Не могли бы вы поместить журнал в метод initClient и посмотреть, срабатывает ли он. - person Ritesh; 22.04.2019
comment
Я использую tap(console.log) для регистрации ответа после карты и получаю массив с двумя элементами - person Dmytro Mysak; 22.04.2019
comment
Похоже, виноват takeUntil. Не могли бы вы удалить takeUntil и просто использовать take(1), чтобы увидеть, выполняется ли код внутри подписки? - person Ritesh; 22.04.2019
comment
Проблема была в google drive api (gapi). Я добавлю больше описания в качестве ответа. - person Dmytro Mysak; 06.05.2019

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

<ng-container *ngIf="data$ | async as data">
    <mat-grid-tile *ngFor="let elem of data | async">  //note it is not data$
        <app-card (input)="returnCartItem(elem)" (click)="goto(elem.header, elem.id)"> 
        </app-card>
    </mat-grid-tile>
</ng-container
person Saksham    schedule 23.04.2019