Javascript 角度HttpClient返回未定义的,而不是数组

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

因此,我有一个API(返回JSON)设置,它打印出一条消息,表明用户正在获取数据,但我的console.log在数据中返回未定义的。。。我的用例必须使用接口吗?或者像我使用的模型完全好吗

如果您还查看我的错误处理并指出错误,则可获得额外积分

我的后端服务ts:

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[];

}