【问题标题】:extract data from service with angular使用角度从服务中提取数据
【发布时间】:2021-07-12 12:29:03
【问题描述】:

我正在尝试从带有 angular 的 json 响应服务中提取 firstname 字段并返回一个包含名字的数组。

这是 json 对象:

{
    "hits": {
        "hits": [
            {
                "_id": "BKZujHgB0urOc7uDCrf5",
                "_index": "names",
                "_score": 1.0,
                "_source": {
                    "firstname": "Alicia"
                },
                "_type": "_doc"
            },
            {
                "_id": "BaZujHgB0urOc7uDL7e2",
                "_index": "names",
                "_score": 1.0,
                "_source": {
                    "firstname": "Alice"
                },
                "_type": "_doc"
            }
        ]
        
}

我创建了一个服务来使用返回 json 对象而不使用 observables 的 web 服务。 appService.ts

public autoComplete(name: string) {

    const params = new HttpParams()
        .set('name', name);
    return this.httpClient.get(this.host, { params});
  

在 app.component.ts 中,我创建了一个调用该服务的函数并在 ngOnInit() 中实现了它,我遵循了自动完成角度材料并稍作修改。但我总是遇到 Cannot read property 'hits' of undefined

的错误
ngOnInit() {
   this.seachText.valueChanges.pipe(
      startWith(''),
      // delay emits
      debounceTime(300),
      // use switch map so as to cancel previous subscribed events, before creating new once
      map(value => this.lookup(value))
      ).subscribe(value => this.results$ = value);
   this.names = this.results$.hits.hits.map(h => h._source.firstname);

   console.log('resultat :', this.names);

  } 

我不知道如何纠正错误,但我想我从服务中提取的 json 对象中提取数据的方式有误

【问题讨论】:

标签: arrays json angular extract subscribe


【解决方案1】:

问题是你的流是异步的,所以当 names 被分配时,肯定还没有发出。

要解决这个问题,您可以使用第二个地图运算符。 这样您就可以根据自己的喜好更改输出,最终值就是您所期望的。

this.searchText.valueChanges
      .pipe(
        startWith(""),
        debounceTime(300),
        map(value => this.appService.autoComplete(value)),
        map(results => results.hits.hits.map(hit => hit._source.firstname))
      )
      .subscribe(value => (this.results = value));

在 StackOverflow 上查看此复制:https://stackblitz.com/edit/stackoverflow-67142850

如果您希望您的 autoComplete 方法返回一个 observable,只需在使用时将 ma​​p 替换为 switchMap

【讨论】:

  • 感谢您的回复,但还是同样的问题无法读取未定义的属性“命中”此自动完成方法public autoComplete(name: string) { const params = new HttpParams() .set('name', name); return this.httpClient.get(this.host, { params}); }我不知道问题出在哪里
  • 恐怕如果不提供更多背景信息,我们将无法在这方面提供更多帮助。
  • 好的 @Simon ,这是我的 app.component.html ` {{option}} ` tslint 加下划线在命中并告诉我“类型'Observable '上不存在属性'命中'”
  • 对于 lint,您应该强烈键入您的对象或使用任何对象。至于运行时错误,首先你应该删除异步管道,因为 results 不是 Observable。
【解决方案2】:

首先,让我使用一个代码 sn-p 来简化错误。

let a;

of(2).subscribe((res) => {
   a = res;
   console.log("res");  // Async code, executed after sync code
})

console.log(a); // syn code. This log is excuted first

输出将是

// undefiend 
// 2;

在您的情况下,您在收到值之前使用results.hits。它实际上做的是读取 undefiend 的命中。这就是发生错误的地方。

要修复该错误,您需要考虑移动 this.names = this.results$.hits.hits.map(h => h._source.firstname); 到您的订阅中以可观察或使用可观察运算符 异步设置值。

【讨论】:

  • 我试图将this.names = this.results$.hits.hits.map(h => h._source.firstname);移动到我的订阅中,但仍然出现同样的错误无法读取未定义的属性“命中”这是我完整的 ngOnInit() ngOnInit() {this.searchText.valueChanges.pipe( startWith(''),debounceTime(300),map(value => this.appService.autoComplete(value)),).subscribe((value) => {this.results = value; this.names = this.results.hits.hits.map(h => h._source.firstname);});}
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-03-28
  • 1970-01-01
  • 1970-01-01
  • 2023-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多