这个问题的标题只是我当前收到的错误,但是我真正需要帮助的是理解可观察性和API调用。无论出于什么原因,我只是无法很好地理解这个概念,我希望有人可能会给出最终解释。
我正在尝试创建一个新的Angular服务,该服务从API检索JSON。然后,我需要将响应映射到模型。由于命名约定古怪,因此此处的工作说明和工作要求可以互换使用。这是我的服务班。
import { CommunicationService } from './communication.service';
import { AiDescription } from '../models/ai-description.model';
import { Observable } from 'rxjs/Observable';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
@Injectable()
export class AiDescriptionService {
requirements: Observable<AiDescription[]>;
private aiDescriptionUrl: string = '/api/core/company/jobdescriptions';
private dataStore: {
requirements: AiDescription[]
};
private _requirements: BehaviorSubject<AiDescription[]>;
private emptyRequestParams = {
"company_id": "",
"carotene_id": "",
"carotene_version": "",
"city": "",
"state": "",
"country": ""
};
readonly caroteneVersion: string = "caroteneV3";
constructor(
private communicationService: CommunicationService
) {
this.dataStore = { requirements: [] };
this._requirements = new BehaviorSubject<AiDescription[]>([]);
this.requirements = this._requirements.asObservable();
}
LoadRequirements(params: Object) {
this.communicationService.postData(this.aiDescriptionUrl, params)
.subscribe(res => {
let jobDescriptions = [];
jobDescriptions = res.jobdescriptions;
jobDescriptions.forEach((desc: { id: string; description: string; }) => {
let aiDescription = new AiDescription();
aiDescription.id = desc.id;
aiDescription.description = desc.description;
});
this.dataStore.requirements = res;
this._requirements.next(Object.assign({}, this.dataStore).requirements);
});
}
CreateRequest(
companyID : string,
caroteneID : string,
city: string,
state: string,
country: string
): Object {
let newRequestParams = this.emptyRequestParams;
newRequestParams.company_id = companyID;
newRequestParams.carotene_id = caroteneID;
newRequestParams.carotene_version = this.caroteneVersion;
newRequestParams.city = city;
newRequestParams.state = state;
newRequestParams.country = country;
this.LoadRequirements(newRequestParams);
return this.dataStore;
}
}
this.communicationService调用的postData()函数在这里:
postData(url: string, jobInformation: any): Observable<any> {
const start = new Date();
const headers = new HttpHeaders({ 'Content-Type': 'application/json' });
const body = JSON.stringify(jobInformation);
const options = { headers };
return this.http.post(url, body, options)
.catch(err => Observable.throw(err))
.do(() => {
this.analyticsLoggingService.TrackTiming('JobPostingService', 'PostSuccess', new Date().getTime() - start.getTime());
}, () => {
this.analyticsLoggingService.TrackError('JobPostingService', 'PostFailure');
});
}
我没有编写postData函数,因此无法对其进行修改。运行单元测试时,出现此错误:“ TypeError:无法读取未定义的属性'forEach'”。
除了简单地修复错误之外,我实际上还试图更好地理解使用Observables,这是我无法从其他来源获得的很好的理解。
答案 0 :(得分:0)
在您的示例中,我建议用明确定义的模型替换any
和Object
。
这是Angular 8的Subscription,Promise和Observable API调用的示例。您可以在此处获取更多信息:https://angular.io/tutorial/toh-pt6。
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders, HttpErrorResponse } from '@angular/common/http';
import { Observable } from 'rxjs';
import { User } from './user.model';
@Injectable({ providedIn: 'root' })
export class UserService {
users: User[];
authHeaders = new HttpHeaders()
.set('Content-Type', 'application/json');
constructor(
private readonly http: HttpClient
) { }
getUsers() {
this.http.get(`https://myApi/users`, { headers: this.authHeaders })
.subscribe(
(data: User[]) => {
this.users = data;
}, (error: HttpErrorResponse) => { /* handle error */ });
}
async getUserPromise(userID: number): Promise<User> {
const url = `https://myApi/users/${userID}`;
return this.http.get<User>(url, { headers: this.authHeaders })
.toPromise();
}
getUserObservable(userID: number): Observable<User> {
const url = `https://myApi/users/${userID}`;
return this.http.get<User>(url, { headers: this.authHeaders });
}
}
我喜欢将班级模型保存在单独的文件中。此示例的user.model.ts
内容如下:
export class User {
constructor(
public id: number,
public username: string,
public displayName: string,
public email: string
) { }
}
为了简洁起见,我没有包括身份验证标头或错误处理;但是,您可能需要根据需要添加它们。