捕获包含在 Angular Observable 中的 JSONAPI

Capturing JSONAPI Included into Angular Observable

我正在尝试学习如何使用 jsonapi 从 Drupal 8 获取内容到我的 Angular 7 应用程序,从 Preston So 的 book,Decoupled Drupal in Practice 开始。它没有展示如何从关系和包含中获取资源。

jsonapi 规范提供了一个包含函数,我可以在其中从节点获取相关资源,而无需进行单独的调用。

使用 http://localhost/jsonapi/node/article/MYUUID?include=field_image 以这种通用格式呈现一个不错的 json 对象。

jsonapi
data
--attributes
--relationships
included

我正在尝试获取包含部分,但我的 ArticleService 仅获取数据的内容,我也想获取包含部分。

我的article.ts

export class Article {
  attributes: object;
  relationships: object;
  included: object;
}

我的article.service.ts

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { catchError, map, mergeMap } from 'rxjs/operators';
import { Article } from '../articles/article';
import { Image } from '../articles/image';

const httpOptions = {
  headers: new HttpHeaders({ 'Content-Type': 'application/json'})
}

@Injectable({
  providedIn: 'root'
})
export class ArticleService {
  private articlesUrl = 'http://localhost/jsonapi/node/article';

  constructor(private http: HttpClient) {}
  getArticle(id: string): Observable<Article>
  {
    if (id) {
      return this.http.get<Article>(this.articlesUrl + '/' + id + '?include=field_image', httpOptions)
        .pipe(
          map(res => res['data'])
         )
        .pipe(
          catchError(this.handleError([]))
    );
    } 
  }
 private handleError<T> (result?: T) {
    return (error: any): Observable<T> => {
      console.error(error);
      return of(result as T);
    }
  }
}

所以我的第一个映射函数是从正文中检索数据对象。我应该能够放大它。我尝试设置 map(res => res['body']),然后map(res => res['']),其中returns没有对象。阅读 rxjs/operators 我看到一些运算符(如 mergeMap、concatMap)失败,因为我不了解如何获取整个响应主体的内容。我的搜索似乎没有什么帮助,所以我正在寻找有关如何获得整个响应的指示。

article.service.ts

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { catchError, map, mergeMap } from 'rxjs/operators';
import { Article } from '../articles/article';
import { Image } from '../articles/image';

const httpOptions = {
  headers: new HttpHeaders({ 'Content-Type': 'application/json'})
}

@Injectable({
  providedIn: 'root'
})
export class ArticleService {
  private articlesUrl = 'http://localhost/jsonapi/node/article';

  constructor(private http: HttpClient) {}
  getArticle(id: string): Observable<Article>
  {
    if (id) {
      return this.http.get<Article>(this.articlesUrl + '/' + id + '?include=field_image', httpOptions);
    } 
  }
 private handleError<T> (result?: T) {
    return (error: any): Observable<T> => {
      console.error(error);
      return of(result as T);
    }
  }
}

component.ts

import { Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { ArticleService } from './article.service'; // import ArticleService service from article.service.ts file

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  name = 'Angular';
  // inject ArticleService to the component
  constructor(private articleService : ArticleService ) {
    this.getArticle(); call getArticle function onInit
  }
  

  getArticle() {
   const id = 12;  // getting article id 12 details
   // subscribe to getArticle service method will call HTTP request and return response
   this.articleService.getArticle(id).subscribe((response)=> {
      // on successful request this block get called
      console.log('response body');
      console.log(response);
      console.log('response actual data');
      console.log(response.body);
    }, (error)=> {
      // on error this block get called like 404, 500 http status 
  })
  }
}