Javascript 角度HttpClient返回未定义的,而不是数组
因此,我有一个API(返回JSON)设置,它打印出一条消息,表明用户正在获取数据,但我的console.log在数据中返回未定义的。。。我的用例必须使用接口吗?或者像我使用的模型完全好吗 如果您还查看我的错误处理并指出错误,则可获得额外积分 我的后端服务ts:Javascript 角度HttpClient返回未定义的,而不是数组,javascript,angular,typescript,angular-httpclient,Javascript,Angular,Typescript,Angular Httpclient,因此,我有一个API(返回JSON)设置,它打印出一条消息,表明用户正在获取数据,但我的console.log在数据中返回未定义的。。。我的用例必须使用接口吗?或者像我使用的模型完全好吗 如果您还查看我的错误处理并指出错误,则可获得额外积分 我的后端服务ts: import { Injectable } from '@angular/core'; import { HttpClient, HttpHeaders, HttpResponse } from '@angular/common/http
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders, HttpResponse } from '@angular/common/http';
import { environment } from '../../../environments/environment';
import { Observable, of } from 'rxjs';
import { catchError, map, tap } from 'rxjs/operators';
import { User } from '../models/user.model';
const SERVICE_URL = 'http://localhost:3000/';
@Injectable()
export class AviorBackendService {
constructor(private client: HttpClient) { }
UserData: any;
httpOptions = {
headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};
/**
* Handle Http operation that failed.
* Let the app continue.
* @param operation - name of the operation that failed
* @param result - optional value to return as the observable result
*/
private handleError<T>(operation = 'operation', result?: T) {
return (error: any): Observable<T> => {
// TODO: send the error to remote logging infrastructure
console.error(error); // log to console instead
// TODO: better job of transforming error for user consumption
this.log(`${operation} failed: ${error.message}`);
// Let the app keep running by returning an empty result.
return of(result as T);
};
}
/**
* Log a failed AviorBackend error.
* @param message - message of the operation that failed
*/
private log(message: string) {
throw new Error(`AviorBackend: ${message}`);
}
getUserCollection() {
return this.client.get<User[]>(SERVICE_URL + 'users');
}
// Get user
getUser(firstname: User): Observable<any> {
const API_URL = `${SERVICE_URL}user/firstname/${firstname}`;
return this.client.get(API_URL, this.httpOptions).pipe(
map((res: Response) => {
return res || {};
}),
catchError(this.handleError())
);
}
/* addUser() {
return this.client.post(SERVICE_URL + 'user', this.UserData, this.httpOptions);
} */
// Add student
addUser(data: User): Observable<any> {
const API_URL = `${SERVICE_URL}user`;
return this.client.post(API_URL, data)
.pipe(
catchError(this.handleError())
);
}
// Update User
putUser(loginId, data: User): Observable<any> {
const API_URL = `${SERVICE_URL}update/${loginId}`;
return this.client.put(API_URL, data, this.httpOptions).pipe(
catchError(this.handleError())
);
}
// Delete student
deleteUser(id): Observable<any> {
const API_URL = `${SERVICE_URL}delete-student/${id}`;
return this.client.delete(API_URL).pipe(
catchError(this.handleError())
);
}
}
我的用户组件ts:
import { Component, OnInit } from '@angular/core';
import { AviorBackendService } from '../services/avior-backend.service';
import { UserCollection } from '../models/user-collection.model';
import { User } from '../models/user.model';
@Component({
selector: 'app-users',
templateUrl: './users.component.html',
styleUrls: ['./users.component.css']
})
export class UsersComponent implements OnInit {
selectedItem: string;
users: UserCollection;
user: User;
firstname: string;
selectedUser: User;
constructor(private aviorBackend: AviorBackendService) { }
ngOnInit() {
this.aviorBackend.getUserCollection().subscribe(data => {
// tslint:disable-next-line: no-string-literal
this.users = data['users'];
console.log(this.users);
});
}
clickItem(firstname) {
this.aviorBackend.getUser(firstname).subscribe(data => {
// tslint:disable-next-line: no-string-literal
this.selectedUser = data['user'];
console.log(this.selectedUser);
});
}
}
在浏览器的“网络”选项卡中,响应是否显示了一个值?如果使用类,应该实例化它,但最好将它定义为一个接口。@JasonWhite是的,确实如此。@Silvermind如何实例化它?我宁愿选择更简单的解决方案。简单的解决方案是将
类用户
更改为接口用户
import { Component, OnInit } from '@angular/core';
import { AviorBackendService } from '../services/avior-backend.service';
import { UserCollection } from '../models/user-collection.model';
import { User } from '../models/user.model';
@Component({
selector: 'app-users',
templateUrl: './users.component.html',
styleUrls: ['./users.component.css']
})
export class UsersComponent implements OnInit {
selectedItem: string;
users: UserCollection;
user: User;
firstname: string;
selectedUser: User;
constructor(private aviorBackend: AviorBackendService) { }
ngOnInit() {
this.aviorBackend.getUserCollection().subscribe(data => {
// tslint:disable-next-line: no-string-literal
this.users = data['users'];
console.log(this.users);
});
}
clickItem(firstname) {
this.aviorBackend.getUser(firstname).subscribe(data => {
// tslint:disable-next-line: no-string-literal
this.selectedUser = data['user'];
console.log(this.selectedUser);
});
}
}
<div class="list-area">
<div class="col-lg-12">
<p class="list-header">Element overview</p>
<div class="form-group">
<label for="filter" class="lb-sm">Filter</label>
<input type="text" class="form-control input-sm" name="filter" id="filter">
</div>
<select size="20" multiple class="form-control" id="elementlist" [(ngModel)]="selectedItem" (click)="clickItem(firstname)">
<option *ngFor="let user of users">
{{user?.lastName}}, {{user?.firstName}}
</option>
</select>
</div>
</div>
<div class="content-area">
<div class="col-lg-12" *ngIf="selectedUser?.id">
<p>Element contents {{selectedUser?.id}}</p>
<div class="col-lg-12">
<div class="form-group">
<label for="firstName" class="lb-sm">First name</label>
<input type="text" class="form-control input-sm" name="firstName" id="firstName" [(ngModel)]="selectedUser.firstName">
</div>
</div>
</div>
</div>
import { User } from './user.model';
export class UserCollection {
user: User[];
}