【问题标题】:How to make an HTTP get() on a local json file using rxjs?如何使用 rxjs 在本地 json 文件上创建 HTTP get()?
【发布时间】:2018-05-22 19:31:27
【问题描述】:

我正在尝试使用 Ionic 打字稿向我的本地 JSON 文件发出请求,并检索我的 JSON 文件中的所有游戏对象。这是我目前所拥有的:

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { map } from 'rxjs/operators/map';
import { catchError } from 'rxjs/operators/catchError';
import { Observable } from "rxjs/Observable";
import { Game } from "../../models/Game";

import { Http, Response, RequestOptions, Headers } from '@angular/http';

/*
  Generated class for the GamesProvider provider.

  See https://angular.io/guide/dependency-injection for more info on providers
  and Angular DI.
*/
@Injectable()
export class GamesProvider {
  constructor(public http: HttpClient) {

  }

  public getGames(): Observable<Array<Game>> {

      return this.http.get('/assets/games.json').pipe(
        map((res: Response) => res.json().games),
        catchError(this.handleError)
      );
  }

  public handleError(error: any) {
      // log error
      // could be something more sofisticated
      let errorMsg = error.message || `Yikes! There was a problem with our hyperdrive device and we couldn't retrieve your data!`
      console.error(errorMsg);

      // throw an application level error
      return Observable.throw(errorMsg);
  }
}

当我调用 getGames() 函数时,我得到的结果如下所示:

operator
    :CatchOperator {caught: Observable, selector: ƒ}
    source
    :Observable {_isScalar: false, source: Observable, operator: MapOperator}
    _isScalar
    :false
    __proto__
    :Object

我期待的是一个可观察的游戏对象数组。

Game.ts:

export class Game {
    gameid: number
    genres: string
    images: string
    name: string
    developer: string
    publisher: string
    date: string
    description: string
    players: number
}

这是我的 JSON 文件的样子:

{
    "games":[
  {
    "Id": 1,
    "name": "007: GoldenEye",
    "genres": "Action/First-Person Shooter",
    "date": "25-Aug-97",
    "images": "007: GoldenEye.png",
    "developer": "Rare",
    "publisher": "Nintendo",
    "description": "A video game released for the Nintendo 64.",
    "players": 4
  },
  {
    "Id": 2,
    "name": "007: The World Is Not Enough",
    "genres": "Action/First-Person Shooter",
    "date": "1-Nov-00",
    "images": "007: The World Is Not Enough.png",
    "developer": "Eurocom",
    "publisher": "Electronic Arts",
    "description": "A video game released for the Nintendo 64.",
    "players": 4
  },
...
...
...
 ]
}

【问题讨论】:

    标签: json ionic-framework rxjs http-get


    【解决方案1】:

    如果你使用 HttpClient 你不应该使用 json(); HttpClient 上的 get() 方法使访问这些数据变得简单:

    ngOnInit(): void {
        this.http.get('/assets/games.json').subscribe(data => {
          this.games = data.games;
        },
        (err: HttpErrorResponse) => {
            if (err.error instanceof Error) {
                console.log('An error occurred:', err.error.message);
            } else {
                console.log(`Backend returned code ${err.status}, body was: ${err.error}`);
            }
        })
    }
    

    然后你可以使用:

    <div *ngFor="let game of games">{{game | json}}</div>
    

    【讨论】:

    • 在 *ngFor, {{ 游戏 | json }} 似乎是一种访问对象的奇怪方式。您将如何以这种方式访问​​单个属性,例如 game.publisher?
    • 仅用于调试。您可以使用 {{game.publisher}}
    【解决方案2】:

    我相信你需要地图而不是管道(并且只是摆脱管道)

    return this.http.get('/assets/games.json').map(
    (res: Response) => res.json().games).catch(this.handleError);
    

    查看文档:https://angular.io/guide/http 您也可以通过订阅来完成

    【讨论】:

    • 我会试试这个并回复你/回答。你知道订阅 vs. 的优势吗?地图?
    【解决方案3】:

    如果您的 Game 类更改为

    export class Game {
        id: number
        genres: string
        images: string
        name: string
        developer: string
        publisher: string
        date: string
        description: string
        players: number
    }
    

    您可以将 http.get 的输出转换为您的 Games 类:

    return this.http.get('/assets/games.json').map(
    (res: Response) => <Game>res.json().games).catch(this.handleError);
    

    处理错误可以使用这个方法

    protected handleError(error: any): Observable<any> {
        console.log(error.message || error);
        const response = 'some error occurred!';
        return Observable.of(response);
      }
    

    【讨论】:

    • 告诉我对象“Observable”上不存在“地图”
    • 我的导入应该是什么样子?我认为这一切都搞砸了。
    猜你喜欢
    • 2017-03-30
    • 1970-01-01
    • 2016-09-28
    • 1970-01-01
    • 2018-04-24
    • 2015-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多