【问题标题】:http API request Angular 12 is empty on the HTML pageHTML页面上的http API请求Angular 12为空
【发布时间】:2021-09-16 18:59:09
【问题描述】:

我在尝试调用 API 时有点困惑。 我首先创建了一个调用 API 的服务:

public getCategories(): Observable<any> {
  let getCategoriesUrl = 'http://localhost:4300/WS/GetCategories';
  return this.http.get<any>(getCategoriesUrl, {
    headers: this.httpOptions, responseType: 'text' as 'json'
  });
}

在我的组件中,我有一个检索数据的方法。我的数据不干净,这就是为什么要清理返回的特殊字符。这也是为什么在我的服务中我不检索特定模型的可观察对象,而是“任何”。这是实现。

private getCategories() {
  this.soapService.getCategories().subscribe(
    (res) => {
      console.log(typeof res);
      res = res.replace(/\n/g, '');
      this.replacement.forEach(
        item => {
          res = res.replace(item, '');
        }
      );
      // res is a string with all data from API call => parsing string to object
      // console.log(res);
      this.categoriesResponseModel = JSON.parse(res);
      console.log('iterate after string parsing');
      // @ts-ignore
      for (const category of this.categoriesResponseModel.CATEGORIES) {
        // console.log(category);
        this.categories.push(category);
      }
      console.log("In get categories");
      console.log("Output  ", this.categories);
    },
    (err) => {
      console.log(err.message);
    },
    () => {
      console.log('Completed - Categories pushed');
    }
  );
}

在方法输出中打印包含以下 console.log 的行上的预期值:console.log("Output ", this.categories);

ngOnInit() {
  console.log('# ngOnInit() called');
  this.getCategories();
  console.log(this.categories)
  console.log("output  " + this.categories)
}

在 ngOnInit 中,我确实有一个空数组作为输出。我测试在 HTML 页面中显示结果:

{{ categories.length }}
<div *ngFor="let category of categories">
  {{ category.CategoryID }} - {{ category.CategoryName }}: {{ category.DocDescription }}
</div>

不幸的是,我得到长度等于0。

【问题讨论】:

  • ngOnInit 中的 console.log 不起作用,也不应该起作用,因为这是一个异步调用。但是,{{ categories.length }} 应该不为零。这条线被调用了多少次... this.categories.push(category); ... ?这是最重要的代码......另外,你在哪里将 this.categories 定义为空数组?
  • 嗨,感谢您的回答。在 this.categorie.push(category) 我的 getCategories 方法中有 3 个条目。这让我很困惑。我不认为它是相关的,但组件是延迟加载的......
  • 延迟加载不会产生任何影响 - push 调用了 3 次吗? - 你在哪里定义 this.categories?
  • 我在组件中定义了这个成员。简单地这样声明:类别:CategoryModel[] = [];
  • 那是因为变更检测需要重新创建数组,你不应该推入它并期望项目被渲染(除非你注入ChangeDetectorRef并在推入所有类别后调用cd.detectChanges() )。

标签: angular api


【解决方案1】:

而不是这个:

// @ts-ignore
for (const category of this.categoriesResponseModel.CATEGORIES) {
  // console.log(category);
  this.categories.push(category);
}

你应该试试这个:

this.categories = [...this.categoriesResponseModel.CATEGORIES];

【讨论】:

  • 谢谢!我要实现这个。我总是忘记展开运算符。
【解决方案2】:

两件事

1.

ngOnInit() {
  console.log('# ngOnInit() called');
  this.getCategories();
  console.log(this.categories)
  console.log("output  " + this.categories)
}

由于订阅中的异步分配,这里的console.log(this.categories) 可能是undefined。请参阅 this 关于异步数据的规范帖子。

  1. 推送到数组不会触发角度变化检测。在这种情况下,您可以直接分配给变量。
this.categories = this.categoriesResponseModel.CATEGORIES;

而不是

  // console.log(category);
  this.categories.push(category);
}

【讨论】:

    【解决方案3】:

    我受到 Octavian Mărculescu 建议使用 ChangeDetectorRef 的启发。 这是组件中 getCategories 的更新代码。

    我还更改了调用 getCategories 的位置并将其放在构造函数中

    constructor(@Inject(TRANSLATION) public readonly lang: Translation,
                private cd: ChangeDetectorRef,
                private soapService: SoapApiService,
                private route: ActivatedRoute) {
      this.getCategories();
    }
    

    这里是实现:

    getCategories(): void {
      const values: CategoryModel[] = [];
      const response = this.soapService.getCategories().subscribe(
        (res) => {
          console.log(typeof res);
          res = res.replace(/\n/g, '');
          this.replacement.forEach(
            item => {
              res = res.replace(item, '');
            }
          );
          // res is a string with all data from API call => parsing string to object
          // console.log(res);
          this.categoriesResponseModel = JSON.parse(res);
          console.log('iterate after string parsing');
          // @ts-ignore
          for (const category of this.categoriesResponseModel.CATEGORIES) {
            // console.log(category);
            values.push(category);
          }
          this.cd.markForCheck();
        },
        (err) => {
          console.log(err.message);
        },
        () => {
          console.log('Completed - Categories pushed');
          this.categories = values;
          console.log(this.categories);
        }
      );
    }
    

    【讨论】:

      猜你喜欢
      • 2023-03-27
      • 2020-04-22
      • 2022-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多