简体   繁体   English

如何在获取方法后将json对象数组解析为打字稿(object)

[英]How to parse an array of json object to typescript (object) after a get method

I am a beginner in angular and start to build my first app.My goal is to build a generic service that will be inherited from others service. 我是angular的初学者,并开始构建我的第一个应用程序。我的目标是构建将要从其他服务继承的通用服务。 I am following the structure of this link to my approach Generic HTTP Service .In read method i`m using Serializer class to convert the response json object to my typescript an it work. 我正在遵循我的方法通用HTTP服务的链接结构。在读取方法中,我使用Serializer类将响应json对象转换为我的打字稿,并且可以正常工作。 I got a map error. 我收到地图错误。 How can I solve it? 我该如何解决?

Service code: 服务代码:

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;
  }

}

UserService: UserService:

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()
    );
  }

UserSerializer: 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;
    }
}

User model: 用户模型:

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 inherited inherited: UserService继承继承:

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

    }

Error: 错误:

core.es5.js:1020 ERROR TypeError: Cannot read property 'map' of undefined core.es5.js:1020错误TypeError:无法读取未定义的属性“ map”

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

First of all, I assume the data that you passed into convertData function is not an array. 首先,我假设您传递给convertData函数的数据不是数组。 Only Array or Observable have map function in this case. 在这种情况下,只有ArrayObservable具有map功能。 Also, chained function has been changed into pipeable operators in RxJS 6 https://github.com/ReactiveX/rxjs/blob/master/doc/pipeable-operators.md 此外,已将链接函数更改为RxJS 6 https://github.com/ReactiveX/rxjs/blob/master/doc/pipeable-operators.md中的可 pipeable operators

Secondly, looking at the error message - I don't think the data value returned from the endpoint has value. 其次,查看错误消息-我认为从端点返回的数据值没有价值。

Third, data.map(item => {this.serializer.fromJson(item)}); 第三, data.map(item => {this.serializer.fromJson(item)}); - if the arrow function inside the map function is wrapped in curly bracket, you need to have return keyword. -如果map函数内部的arrow函数用大括号括起来,则需要具有return关键字。 in other word, data.map(item => {this.serializer.fromJson(item)}); 换句话说, data.map(item => {this.serializer.fromJson(item)}); should be data.map(item => this.serializer.fromJson(item)); 应该是data.map(item => this.serializer.fromJson(item)); or data.map(item => {return this.serializer.fromJson(item)}); data.map(item => {return this.serializer.fromJson(item)});

Use subscribe instead of map to return the response. 使用订阅而不是地图返回响应。

 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 has changed the implementation of using observable map function BTW RXJs6更改了使用可观察地图功能的实现

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM