【问题标题】:How to retrieve just one object from JSON file using TypeScript Angular?如何使用 TypeScript Angular 从 JSON 文件中仅检索一个对象?
【发布时间】:2021-06-27 04:26:39
【问题描述】:

我发出了一个非常普通的 HTTP 请求来从 JSON 文件中获取一个对象。但我注意到我得到了所有文件的数据,而不是唯一需要的对象。 遵循我的代码演示了我如何创建一个类来获取所需的数据,但由于某种原因它仍然无法按计划工作。

JSON 文件 (DB.json) => 我只需要(文章)

{
    "articles": [
      {
        "id": "1",
        "title": "Title 1",
        "body": "what ever ... ",
        "date": "14/03/2020",
        "rating": 4,
        "pic": "../../assets/images/cat.jpg"
      },
      {
        "id": "2",
        "title": "Title 2",
        "body": "what ever ... ",
        "date": "15/03/2020",
        "rating": 5,
        "pic": "../../assets/images/dog.jpg"
      }
    ],
    AnotherTableName [ ... etc ],
    AnotherTableName [ ... etc ]
}

article.ts => 类

export class Article {
    id: string;
    title: string;
    body: string;
    date: Date;
    rating: number;
    pic: string;
}

组件.ts

export class ArticleComponent implements OnInit {

  constructor(private httpGetArticles: ArticleService) { }
  
  errMess: string;
  articles: Article[];

  ngOnInit(){
    this.httpGetArticles.getArticles().subscribe(
     data =>  this.articles = data,
     errmess => this.errMess = <any>errmess,
     () => console.log(this.articles));
    
  }

}

component.html

<p *ngFor="let artcl of articles">
    <span>artcl.title</span>>
</p>

服务

  getArticles(): Observable<Article[]> {
    return this.http.get<Article[]>("./assets/DB.json")
    .pipe(catchError(this.handleHttpErrService.handleError));
  }

console.log(.. 结果

Object { 
articles: Array [ {…}, {…} ]
feedback: Array(13) [ {…}, {…}, {…}, … ]
leaders: Array(4) [ {…}, {…}, {…}, … ]
promotions: (1) […]

尽管我得到了如图所示的对象,但我也得到了以下错误(我认为是因为我将 NgFor 用于一个名为文章的对象,但检索到的数据提出了一种不同的格式“整个 JSON 文件”)

ERROR Error: Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays.

所以我只需要检索转换后的数据(文章)而不是所有 JSON 文件

【问题讨论】:

    标签: json angular typescript angular-http


    【解决方案1】:

    理想情况下,后端应该支持返回对象的特定属性。为了快速修复,您可以将 RxJS pluck 运算符通过管道传递到客户端中的 HTTP 请求

    服务

    import { catchError, pluck } from 'rxjs/operators';
    
    getArticles(): Observable<Article[]> {
      return this.http.get<Article[]>("./assets/DB.json").pipe(
        pluck('articles'),
        catchError(this.handleHttpErrService.handleError)
      );
    }
    

    此外,我还建议进行以下更改。

    1. 使用 TS 接口而不是类进行类型检查。 When to use an interface or a class in Typescript?

    article.ts

    export interface Article {
      id: string;
      title: string;
      body: string;
      date: Date;
      rating: number;
      pic: string;
    }
    
    1. 在组件模板中使用async 管道,而不是控制器中的订阅。

    组件

    import { throwError } from 'rxjs';
    import { catchError } from 'rxjs/operators';
    
    export class ArticleComponent implements OnInit {
      constructor(private httpGetArticles: ArticleService) { }
      
      articles$: Observable<Article[]>;
    
      ngOnInit(){
        this.articles$ = this.httpGetArticles.getArticles().pipe(
          catchError(error => {
            console.log('Error fetching articles:', error);
            return throwError(error);
          }
        );
      }
    }
    

    模板

    <ng-container *ngIf="(articles$ | async) as articles">
      <div *ngFor="let article of articles">
        ...
      </div>
    </ng-container>
    

    【讨论】:

    • 这是我的服务的样子 .... getArticles(): Observable
      { return this.http.get
      ("./assets/DB.json ") .pipe(catchError(this.handleHttpErrService.handleError)); }
    • @MOHAMEDABUELATTA:请发布问题的任何更新。
    • @MOHAMEDABUELATTA:您可以在catchError 运算符之前输入pluck。我已经更新了答案。
    • 它可以工作,但我不能像 pluck('articles')、catchError 一样连续使用 2 个管道...所以我删除了 catchError 因为它给了我一个错误.. 无论如何谢谢
    • 您应该能够输入任意数量的运算符。如果您想强制类型检查而不是使用any,请使用map 运算符而不是pluck 并转换类型:map((data: any) =&gt; data['articles'] as Article[])
    猜你喜欢
    • 1970-01-01
    • 2018-11-21
    • 2012-02-02
    • 2020-11-28
    • 1970-01-01
    • 2017-12-08
    • 1970-01-01
    • 1970-01-01
    • 2018-10-30
    相关资源
    最近更新 更多