我是angular的初学者,并开始构建我的第一个应用程序。我的目标是构建将要从其他服务继承的通用服务。我正在跟踪方法Generic HTTP Service的链接结构。在读取方法中,我使用Serializer类将响应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;
}
}
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:
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错误TypeError:无法读取以下内容的属性“地图” 未定义
位于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)
答案 0 :(得分:0)
使用订阅而不是地图来返回响应。
$ dig aridns.com NS @a.gtld-servers.net
; <<>> DiG 9.11.3-1ubuntu1.1-Ubuntu <<>> aridns.com NS @a.gtld-servers.net
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 2552
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 4, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;aridns.com. IN NS
;; AUTHORITY SECTION:
aridns.com. 172800 IN NS dns1.ausregistry.net.au.
aridns.com. 172800 IN NS dns1-1.ausregistry.net.au.
aridns.com. 172800 IN NS dns1-2.ausregistry.net.au.
aridns.com. 172800 IN NS dns2-1.ausregistry.net.au.
;; Query time: 68 msec
;; SERVER: 192.5.6.30#53(192.5.6.30)
;; WHEN: Mon Sep 03 19:28:07 EST 2018
;; MSG SIZE rcvd: 139
BTW RXJs6更改了implementation of using observable map function
答案 1 :(得分:0)
首先,我假设您传递给convertData
函数的数据不是数组。
在这种情况下,只有Array
或Observable
具有map
功能。
另外,RxJS 6中的链接函数已更改为pipeable operators
https://github.com/ReactiveX/rxjs/blob/master/doc/pipeable-operators.md
其次,查看错误消息-我认为从端点返回的数据值没有值。
第三,data.map(item => {this.serializer.fromJson(item)});
-如果map函数内部的箭头函数用大括号括起来,则需要使用return
关键字。
换句话说,data.map(item => {this.serializer.fromJson(item)});
应该是data.map(item => this.serializer.fromJson(item));
或data.map(item => {return this.serializer.fromJson(item)});