0

我正在尝试制作简单的网络新闻阅读器,主要基于谷歌新闻 api ( https://newsapi.org/s/google-news-api )。我已经像往常一样做了所有服务、模型等,但我在将数据映射到具体接口时遇到了问题。Google api 以这种格式返回端点(“头条新闻”)数据之一:

{
    "status": "ok",
    "totalResults": 38,
    "articles": [
       {
       "source": {
            "id": "the-new-york-times",
            "name": "The New York Times"
       },
      "author": null,
      "title": "Hong Kong Protesters Clash with Police Amid Fears of Mob 
       Violence - The New York Times",
      "description": "some description",
      "url": "https://www.nytimes.com/2019/08/11/world/asia/hong-kong- 
       protest.html",
      "urlToImage": 
      "https://static01.nyt.com/images/2019/08/11/world/11hongkong15/
       11hongkong15-facebookJumbo.jpg",
      "publishedAt": "2019-08-11T11:19:03Z",
      "content": "some content… [+751 chars]"
       },
      (...and many many more articles)
    ]
}

我只需要文章。而且我知道,如果我从这样的 api 获取这些数据,我可以调用 myvariablename.articles,但这对我来说似乎不合适。

我首先尝试的是使用 rxjs map 方法进行映射。但是我在控制台中收到错误,即 Articles 模型中没有属性文章。所以我准备了响应模型和嵌套文章作为响应模型(接口)内部的属性。我得到完全相同的错误。我在想,在 Observable 方法中定义可能有一些问题,所以我切换到 Response 但没有运气,现在我从我订阅的组件中收到错误,并使用服务方法,它说:“类型响应 [ ] 不可分配给类型 Article[]"

头条新闻.service.ts

(...all imports)

export class TopNewsService {

(... ommited defining of variables like url etc.)

  public getAll(): Observable<Response[]> {
    return this.httpClient
      .get<Response[]>(`${this.url}/${this.endpoint}?country=us&apiKey=${this.token}`)
      .pipe(
        map(response => response.articles),
        catchError(this.handleError)
      );
  }
(...error handling)
}

文章.ts

export interface Article {
  source: {
    id: string;
    name: string;
  };
  author: string;
  title: string;
  description: string;
  url: string;
  urlToImage: string;
  publishedAt: string;
  content: string;
}

响应.ts

import { Article } from './article';

export interface Response {
  status: string;
  totalResults: number;
  articles: Article;
}

头条新闻-component.ts

(...all imports)

export class TopNewsComponent implements OnInit {

  articles: Article[];

  constructor(private http: HttpClient, private topNewsService: TopNewsService) { }

  ngOnInit() {
    this.getAllProjects();
  }

  getAllProjects() {
    this.topNewsService.getAll().subscribe(data => {
      this.articles = data;
      console.log(this.articles)
    },
      (err: string) => {
        alert(err);
      });
  }
}

我希望能够在服务中映射数据并仅返回文章,然后(如果可能的话)在我的组件中获取这些数据并将其分配给定义类型为 Article[] 的已创建变量。

4

1 回答 1

1

你正在使用

this.httpClient.get<Response[]>

这意味着您希望 Google 返回一个响应数组。但这不是它返回的内容。它返回一个 Response. 所以应该是

this.httpClient.get<Response>

并且由于您(尝试)将此响应映射到文章数组,因此您的服务返回的 observable 是 an Observable<Article[]>,而不是 an Observable<Response[]>。所以应该是

public getAll(): Observable<Article[]> {

这个界面

export interface Response {
  status: string;
  totalResults: number;
  articles: Article;
}

也是错误的。回复不包含一篇文章。它包含一系列文章。查看 JSON:

{
  "status": "ok", // one status string
  "totalResults": 38, // one totalResults number
  "articles": [ // an **array** of articles
    ..
  ]
}

所以应该是

export interface Response {
  status: string;
  totalResults: number;
  articles: Article[];
}
于 2019-08-11T13:45:19.790 回答