【问题标题】:Angular 6 HttpClient.get Observable does not assign valueAngular 6 HttpClient.get Observable 不赋值
【发布时间】:2018-07-17 02:49:58
【问题描述】:

我想答案会很明显,但它仍然逃避我。我是使用 observables 的新手,现在我面临着从一个值分配值的问题。如果我将它(this._apps)定义为一个 Observable 并使用 subscribe 从视图向服务询问,我就成功了(但我的口味很复杂(地图内的三个级别只是为了返回另一个带有数组的 observable,然后另一个订阅先前分配变量的函数和视图中的另一个订阅以最终显示信息),效率低下,最重要的是我无法再次“正确”获得它)。任务非常简单。给定类 Application

export class Application {
  name: string;
  baseUrl: string;
  deprecated: boolean;
}

还有服务(只是相关代码)

private _apps: Application[] = [];

constructor(private _http: HttpClient) {
  this.getAllApplications().subscribe(apps => {
    console.log('Apps subscriber');
    this._apps = apps;
    console.log('Apps subscriber Ends ' + apps);
  },
  err => {
    console.log(err.status); // 401
    console.log(err.error.error); // undefined
    console.log(JSON.parse(err.error).error); // unauthorized
  });
}

private getAllApplications() {
  return this._http.get<Application[]>('http://development:4300/api/v1/apps');
}

从构造函数中触发了从 WebAPI 获取信息的函数,并且远程调用成功,但是如果我尝试从代码中的任何位置调用变量 this._apps 是一个空数组。我无法确定订阅函数中参数“apps”的类型,但由于某种原因无法分配它,给出的最佳答案是它是我尝试的一个函数(参见我的第一次更新)。目前它在控制台“[object Object]”中返回,但是apps[0]给出了未定义的,所以它是一个空数组。

这是控制台输出,刚刚启动应用程序:

Angular 正在开发模式下运行。调用 enableProdMode() 以启用生产模式。 刷新应用缓存调用http://development:4300/api/v1/atbc-apps 应用订阅者 应用订阅者结束 [object Object]

我正在尝试this solution 以及我忘记的许多其他方法(使用更现代的 HttpClient 而不是我以前使用的 Http),那么我做错了什么?

更新 1

我把构造函数改成这样:

constructor(private _http: HttpClient) {
  this.getAllApplications().subscribe(apps => {
    console.log('apps length ' + apps.length);
    this._apps = apps;  // Remember private _apps: Application[] = [];
    console.log('Apps subscriber Ends ' + apps.toString);
  },
    err => {
      console.log(err.status); // 401
      console.log(err.error.error); // undefined
      console.log(JSON.parse(err.error).error); // unauthorized
    });
}

以及调用此函数的声明:

private getAllApplications(): Observable<Application[]> {
   // the exactly the same as before
}

现在我从控制台得到了这个:

应用程序长度未定义

Apps 订阅者结束 function () { if (this instanceof Promise) { return PROMISE_OBJECT_TO_STRING; } return originalObjectToString.apply(this, arguments); }

这就是我所说的功能。关于为什么即使没有错误(编译时也没有,运行时也没有),返回的对象不是真正的应用程序数组的任何想法?

【问题讨论】:

    标签: angular6 angular-httpclient rxjs6


    【解决方案1】:

    改变这一行:

    private _apps: Application[] = [];
    

    到:

    _apps: Application[] = [];
    

    默认设置为公开。那么这一行就会看到:

    this._apps = apps;
    

    【讨论】:

    • 我做到了,但问题是一样的。最重要的是 this._apps 在服务内部是可见的(它在外部没有使用,并且可以通过公共方法访问);否则,我无法编译代码。事实上,运行它不会在您的更改之前或之后给出任何错误,但也不会分配它。感谢您的宝贵时间。
    【解决方案2】:

    最后我想是一种使用 Observables 的心态,我尝试构建一种缓存,所以我能做到的唯一方法(如果有更好的方法让我知道)是使用视图来填写缓存。我无法从服务本身执行此操作,因为从视图调用函数是同步的,而填写数组是异步的。所以我必须创建一个公共的 setApplicationCache 过程,该过程在从视图调用服务后填写,它调用 setApplicationCache( Application[] ) 函数,其余的工作,因为它只需要缓存来进行过滤和其他操作或使用它来自其他页面,没有一次又一次地调用数据库。

    这是第一个视图中的代码(主页面)

    ngOnInit() {
      this._myService.getAllApplications().subscribe(arrObjApps => {
      this._myService.setApplicationsCache(arrObjApps)
      this.listApps = this._myService.getApplications(true);
    });    
    

    并且该服务具有以下功能:

      private _apps: Application[] = [];
    
      getAllApplications(): Observable<Application[]>  {
        return this._http.get('http://development:4300/api/v1/atbc-apps').pipe(
          map( (response: Response) => {
            let results = response.json().data.map( app => {
            return new Application(app.name, app.baseUrl, app.deprecated);
          });
          return results;
        })
      );
    }
    
    getApplication(appName: string): Application {
      return this._apps.find(app => app.name == appName);
    }
    
    getApplications(onlyActives: boolean): Application[] {
      if (onlyActives) {
        return this._apps.filter(app => app.deprecated == false);
      } else {
        return this._apps;
      }
    }
    

    正如我所说,解决方案应该是显而易见的。再次强调使用可观察对象所需的异步思维方式。

    【讨论】:

      猜你喜欢
      • 2019-07-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多