如何跳过.map Ionic 4 Observables中的迭代

时间:2019-02-22 11:34:51

标签: observable ionic4

我正在开发一个Ionic 4应用程序,该应用程序从wordpress API中提取帖子。我正在使用mergeMap和forkjoin获取特色图片,以在主帖子页面上获取帖子特色图片。

当有特征图像要获取时,以下代码可以正常工作,但是如果没有特征图像,那么我只是从throwError中得到一个错误。我似乎无法记录错误。

%h – Remote hostname (or IP address if the resolveHosts attribute is set to false; by default the value is false).
%l – Remote logical user name; this is always a hyphen (-).
%u – Remote user that has been authenticated. In the example, “admin” and a hyphen (-). If there is none, it’s a hyphen (-).
%t – Date and time in common log file format.
%r – The first line of the request. In the example, “GET / HTTP/1.1” (note that this is configured to be shown within quotes (“”)).
%s – The HTTP status code of the response. In the example 200 is the OK status.
%b – Bytes sent count, excluding HTTP headers, and shows a hyphen (-) if zero.

这是我的home.page.ts文件

dumpbin /EXPORTS bcryptcpp.lib

这是我使用wordpress api的服务文件

ERROR Something went wrong ;)

我检查一下是否import { Component } from '@angular/core'; import { Router } from '@angular/router'; import { LoadingController } from '@ionic/angular'; import { WordpressRestapiService, Post } from '../services/wordpress-restapi.service'; @Component({ selector: 'app-home', templateUrl: 'home.page.html', styleUrls: ['home.page.scss'], }) export class HomePage { categoryId: number; private posts : Post[] = []; constructor( public loadingController: LoadingController, private router: Router, private wordpressService: WordpressRestapiService) { } async ngOnInit() { const loading = await this.loadingController.create(); await loading.present(); this.loadPosts().subscribe((posts: Post[]) => { this.posts = posts; loading.dismiss(); }); } loadPosts() { return this.wordpressService.getRecentPosts(this.categoryId); } openPost(postId) { this.router.navigateByUrl('/post/' + postId); } } 才返回帖子,否则请进行api调用以获取精选图片,但这似乎永远不会返回帖子。 import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable, forkJoin, throwError, empty } from 'rxjs'; import { catchError, map, mergeMap } from 'rxjs/operators'; @Injectable({ providedIn: 'root' }) export class WordpressRestapiService { baseRestApiUrl: string = 'http://example.com/wp-json/wp/v2/'; constructor(private httpClient: HttpClient) { } getRecentPosts(categoryId: number, page: number = 1): Observable<any[]> { // Get posts by a category if a category id is passed let category_url = categoryId ? ("&categories=" + categoryId) : ""; return this.httpClient.get(this.baseRestApiUrl + "posts?page=" + page + category_url).pipe( map((res: any) => res), mergeMap((posts: any[]) => { if (posts.length > 0) { return forkJoin( posts.map((post: any) => { if (post.featured_media === 0) { console.log('fired'); post.media = {}; return new Post(post); } else { return this.httpClient.get(this.baseRestApiUrl + "media/" + post.featured_media).pipe( map((res: any) => { let media: any = res; post.media = new Media(media); return new Post(post); }), catchError(error => { return throwError('Something went wrong ;)'); }) ); } }) ); } return empty(); }), catchError(error => { return throwError('Something went wrong ;)'); }) ); } } export class Post { author: number; categories: number[]; comment_status: string; content: object; date: string; date_gmt: string; excerpt: object; featured_media: number; format: string; guid: object; id: number; link: string; media: object; meta: object; modified: string; modified_gmt: string; ping_status: string; slug: string; status: string; sticky: boolean; tags: number[]; template: string; title: object; type: string; _links: object; constructor(values: Object = {}) { Object.assign(this, values); } } export class Media { date: string; date_gmt: string; guid: object; id: number; link: string; modified: string; modified_gmt: string; slug: string; status: string; type: string; title: object; author: number; comment_status: string; ping_status: string; meta: object; template: string; alt_text: string; caption: object; description: object; media_type: string; mime_type: string; media_details: object; post: number; source_url: string; constructor(values: Object = {}) { Object.assign(this, values); } } 被调用,但是loadingCtrl永远不会关闭,帖子也不会显示。

如果没有特色图片但返回所有帖子,我如何只为post.media返回一个空对象?

更新:基于David所说的,我使用以下内容更新了WordpresRestapiService中的getRecentPosts()函数。这给了我想要的结果。

post.featured_media === 0

}

1 个答案:

答案 0 :(得分:1)

我认为问题在于,您正在向要传递给forkJoin的数组添加一个Post,而不是一个Observable of Post。

您可以尝试

import { Observable, forkJoin, throwError, empty, of } from 'rxjs';
...
if (post.featured_media === 0) {
  console.log('fired');
  post.media = {};
  return of(new Post(post));
}

在旁注中,我会避​​免像那样使用catchError。本质上,它正在吞噬任何JavaScript错误(以及不成功的HTTP响应)。这就是为什么在这种情况下看不到有用的错误的原因。

参考: (这些不是官方文档,但我发现它们更具可读性) 堆栈溢出认为这些链接是代码...

https://www.learnrxjs.io/operators/combination/forkjoin.html
https://www.learnrxjs.io/operators/creation/of.html
https://www.learnrxjs.io/operators/error_handling/catch.html