【问题标题】:How to parse an array of json object to typescript (object) after a get method如何在get方法之后将json对象数组解析为打字稿(对象)
【发布时间】:2019-02-08 22:56:27
【问题描述】:

我是 Angular 的初学者并开始构建我的第一个应用程序。我的目标是构建一个从其他服务继承的通用服务。我遵循这个链接的结构到我的方法Generic HTTP Service。在读取方法中,我使用序列化器类将响应json对象转换为我的打字稿,它可以工作。我遇到地图错误。我该如何解决?

服务代码:

import { Injectable } from '@angular/core';
import { Http, Headers } from '@angular/http';
import 'rxjs/add/operator/map';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Resource } from '../models/resource.model';
import { Observable } from 'rxjs/Observable';
import { Serializer } from '../serializer/serializer';
import { AuthenticationService } from './authentication.service';

@Injectable()
export class SharedService<T extends Resource> {

  constructor(
    private httpClient: HttpClient,
    private url: string,
    private endpoint: string,
    private authentication: AuthenticationService,
    private serializer: Serializer
  ) { }


  create(resource: T) {
    let headers = new HttpHeaders();
    headers = headers.set('Content-Type', 'application/json; charset=utf-8');
    return this.httpClient.post(`${this.url}/${this.endpoint}`, JSON.stringify(resource), { headers: headers });
  }



  //PUT
  update(item: T): Observable<T> {
    return this.httpClient.put<T>(`${this.url}/${this.endpoint}`, JSON.stringify(item), { headers: this.addHeaders() })
      .map(data => this.serializer.fromJson(data) as T);
  }



  //GET
  read(id: number): Observable<T> {
    return this.httpClient.get(`${this.url}/${this.endpoint}/${id}`, { headers: this.addHeaders() })
      .map((data: any) => this.serializer.fromJson(data) as T);
  }

  //GET ALL
  list(): Observable<T[]> {
    return this.httpClient.get<T>(`${this.url}/${this.endpoint}` , {headers : this.addHeaders()})
      .map((data: any) =>
        this.convertData(data.items));
  }

  protected convertData(data: any): T[] {

    return data.map(item => {this.serializer.fromJson(item)});
  }

  protected addHeaders() {
    let token = ('Bearer ' + this.authentication.getToken()).valueOf();
    let headers = new HttpHeaders();
    headers = headers.set('Content-Type', 'application/json; charset=utf-8').set('Authorization', token);
    return headers;
  }

}

用户服务:

import { Injectable } from '@angular/core';
import { SharedService } from './shared.service';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { User } from '../models/user/user.model';
import { AuthenticationService } from 'app/service/authentication.service';
import { UserSerializer } from '../serializer/user-serializer';
import { NgForm } from '@angular/forms';

@Injectable()
export class UserService extends SharedService<User>{

  constructor(httpClient: HttpClient, authenticate: AuthenticationService) {
    super(httpClient,
      'http://localhost:8084/SuperCloud/webresources',
      'user',
      authenticate,
      new UserSerializer()
    );
  }

用户序列化器:

import { User } from "../models/user/user.model";
import { Serializer } from "./serializer";
import { Resource } from "../models/resource.model";

export class UserSerializer extends Serializer {
    fromJson(json: any): Resource {
        const user = new User();
        user.id = json.id;
        user.name = json.name;
        user.surname = json.surname;
        user.email = json.email;
        user.phoneNumber = json.phoneNumber;
        user.password = json.password;
        user.username = json.username;
        user.active = json.active;
        console.log('serializer');
        console.log(user);
        return user;
    }
}

用户模型:

import { Resource } from "../resource.model";

export class User extends Resource{
    username: string;
    email: string;
    name: string;
    surname: string;
    phoneNumber: string;
    password?: string;
    active : boolean;
}

UserService 继承继承:

 ngOnInit() {
        this.userService.list().subscribe(
            (data) => console.log(data)
       );
 
    }

错误:

core.es5.js:1020 ERROR TypeError: Cannot read property 'map' of 未定义

在 UserService.SharedService.convertData (shared.service.ts:53)
在 MapSubscriber.eval [作为项目] (shared.service.ts:48)
在 MapSubscriber._next (map.js:79)
在 MapSubscriber.Subscriber.next (Subscriber.js:95)
在 MapSubscriber._next (map.js:85)
在 MapSubscriber.Subscriber.next (Subscriber.js:95)
在 FilterSubscriber._next (filter.js:90)
在 FilterSubscriber.Subscriber.next (Subscriber.js:95)
在 MergeMapSubscriber.notifyNext (mergeMap.js:151)
在 InnerSubscriber._next (InnerSubscriber.js:25)

【问题讨论】:

    标签: json angular typescript


    【解决方案1】:

    首先,我假设您传递给convertData 函数的数据不是数组。 在这种情况下,只有 Array 或 Observable 具有 map 功能。 此外,在 RxJS 6 中,链式函数已更改为 pipeable operators https://github.com/ReactiveX/rxjs/blob/master/doc/pipeable-operators.md

    其次,看报错信息——我认为端点返回的数据值没有价值。

    第三,data.map(item =&gt; {this.serializer.fromJson(item)});——如果map函数内的箭头函数用大括号括起来,则需要有return关键字。 换句话说,data.map(item =&gt; {this.serializer.fromJson(item)}); 应该是 data.map(item =&gt; this.serializer.fromJson(item)); 或 data.map(item =&gt; {return this.serializer.fromJson(item)});

    【讨论】:

    • 只有那一秒才没有问题。我根据您的建议更改了我的代码。 list() : Observable{ return this.httpClient.get(${this.url}/${this.endpoint}, { headers: this.addHeaders() }).pipe( map((data : T[]) => (this.convertData (data))) ) } protected convertData(data: any): T[] { return data.map(item => { return this.serializer.fromJson(item) }); }
    • 该功能正在运行!!我可以为初学者提供一个链接,其中包含管道和链示例
    • RxJS 最近将他们的文档网站移至 rxjs-dev.firebaseapp.com,这是一个很好的起点。
    【解决方案2】:

    使用 subscribe 而不是 map 来返回响应。

     return this.httpClient
      .put<T>(`${this.url}/${this.endpoint}`, JSON.stringify(item), {
        headers: this.addHeaders()
      })
      .subscribe(data => this.serializer.fromJson(data) as T);
    

    BTW RXJs6 已更改implementation of using observable map function

    【讨论】:

    • 我已经订阅了我的组件,我的问题出在 list() 函数中。
    • 您仍然可以订阅服务类。 list(): Observable&lt;T[]&gt; { return this.httpClient .get&lt;T&gt;(${this.url}/${this.endpoint}, { headers: this.addHeaders() }).subscribe((data: any) =&gt; this.convertData(data.items)); }
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-02-03
    • 2014-12-02
    • 1970-01-01
    • 2020-05-02
    • 2018-09-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多