api 服务在 observable 中变得未定义

api service becoming undefined in observable

下面是我的 app.component.js 我的 angular 6 ionic 4 应用程序。我有一个 observable,它会触发对 api 服务的调用,以每 2 分钟检查一次新通知。第一个调用成功触发,之后,我收到一条错误消息,说 can't find listModel of undefined 指的是我的行 await this.api.listModel('Notification' 。这怎么变成未定义的?我可以做些什么来绕过这个问题?

...
import { LoadingService } from './loading.service';
import { apiService } from './...-api.service';
...

@Component({
  selector: 'app-root',
  templateUrl: 'app.component.html',
  styleUrls: ['./app.component.scss'],
})
export class AppComponent {
  public appPages = [
    {
      title: 'Home',
      url: '/notifications',
      icon: 'notifications'
    },
  ...
  public title = 'Places';
  public addrKeys: string[];
  public addr: object;
  public hasUnactionedNotification: any = false;
  public notificationObservable: any;
  public account: any;
  public initials: any;

  constructor(
    private platform: Platform,
    private api: apiService,
    ...
  ) {
    this.initializeApp();
    this.initializeNotifAndInitials();
  }

  ...

  async initializeNotifAndInitials() {
    this.refreshNotifications();
    this.account = await this.accountService.getAccount();
    this.initials = this.account.firstName != null ? this.account.firstName.charAt(0) + this.account.lastName.charAt(0) : '';
    this.notificationObservable = interval(0.5 * 60 * 1000);
    this.notificationObservable.subscribe(this.refreshNotifications);
  }

  async refreshNotifications() {
    let notifications = await this.api.listModel('Notification', null, null, {
      page: 0,
      size: 15
    });
    this.hasUnactionedNotification = !!_.filter(notifications, {
      isActioned: false
    }).length;
    //boot out users who are no longer logged in
    this.account = await this.accountService.getAccount();
    if (!this.account) {
       this.router.navigateByUrl('/login');
    }
  }

}

这里是 api 服务调用

import { Injectable } from '@angular/core';
import { Observable, of, throwError } from 'rxjs';
import { HttpClient, HttpHeaders, HttpErrorResponse, HttpParams } from '@angular/common/http';
import { catchError, tap, map } from 'rxjs/operators';
import { SessionService } from './session.service';
import { environment } from '../environments/environment';
import * as _ from 'lodash';
import * as moment from 'moment-timezone';

@Injectable({
  providedIn: 'root'
})
export class FinaeoApiService {
  pageSize: any = 20;

  constructor(
    private http: HttpClient,
    private sessionService: SessionService,
  ) { }

    async listModel(modelName, modelId, secondModelName, opts) {
    const options = await this.getRequestOptions();
    let params = <any> {
      page: _.get(opts, 'page', 0),
      size: _.get(opts, 'size', this.pageSize),
    };
    if (modelId === null && secondModelName === null) {
      params.disableCompany = _.get(opts, 'disableCompany', false);
    };
    if (!_.isEmpty(opts.filters)) {
      let filters = [];
      _.each(opts.filters, filter => {
        filters.push(`${filter.attribute},${filter.action}:${filter.value}`);
      });
      params.filter = filters.join(',');
    }
    if (!_.isEmpty(opts.sort)) {
      params.sort = opts.sort.join(',');
    }
    options.params = new HttpParams({
      fromObject: params
    });
    if (modelId === null && secondModelName === null) {
      return this.http.get(`${environment.apiUrl}/${modelName.toLowerCase()}`, options).toPromise().then(this.extractData).catch(this.handleError);
    } else {
      return this.http.get(`${environment.apiUrl}/${modelName.toLowerCase()}/${modelId}/${secondModelName.toLowerCase()}`, options).toPromise().then(this.extractData).catch(this.handleError);
    }
  }

我认为问题是你需要 .bind(this)

即:

this.notificationObservable.subscribe(this.refreshNotifications.bind(this));

但我个人不喜欢这种语法,我宁愿选择

this.notificationObservable.subscribe(() => this.refreshNotifications());