Angular: невозможно прочитать свойство 'forEach' из неопределенного - проблема (даже если должна быть определена) - PullRequest
0 голосов
/ 21 февраля 2020

Я пытаюсь получить доступ к данным о пользователях в моем пользовательском компоненте, я вызываю logUsers () для печати пользовательских данных на консоль. Вот мой компонент:

import { Component, OnInit } from '@angular/core';
import { GetDbDataService} from '../get-db-data.service';
import { User } from '../user';

@Component({
  selector: 'app-users',
  templateUrl: './users.component.html',
  styleUrls: ['./users.component.css']
})
export class UsersComponent implements OnInit {
  users: User[];
  constructor(private getDbDataService: GetDbDataService) { }

  ngOnInit() {
    this.getUsers();
    this.logUsers();
  }

  getUsers(): void {
    this.getDbDataService.getUsers()
    .subscribe(users => this.users = users);
  }

  logUsers(): void{
    this.users.forEach((User) =>{
      console.log("id: " + User.id + " password: " + User.password);
    })
  }
}

мой getDbDataService выглядит следующим образом:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, of }  from 'rxjs';
import { User } from './user';
import { catchError, map, tap } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class GetDbDataService {

  private usersURL = 'api/users'; 
  constructor(private http: HttpClient) { }

  getUsers (): Observable<User[]> {
    return this.http.get<User[]>(this.usersURL)
      .pipe(
        tap(_ => this.log('fetched users')),
        catchError(this.handleError<User[]>('getUsers', []))
      );
  }

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

  private log(message: string) {
    console.log(message)
  }
}

выборка пользовательских данных должна работать, когда я получаю журнал «выбранных пользователей». Http-запросы обрабатываются фиктивным бэкэндом: https://github.com/angular/in-memory-web-api/blob/master/README.md; Мой файл in-memory-data.service.ts, используемый * in-memory-web-api angular, выглядит следующим образом:

import { Injectable } from '@angular/core';
import { InMemoryDbService } from 'angular-in-memory-web-api';
import { Observable, of }  from 'rxjs';
import { delay } from 'rxjs/operators';
import { User } from './user';

// documentation: https://github.com/angular/in-memory-web-api/blob/master/README.md

@Injectable({
  providedIn: 'root'
})

export class InMemoryDataService implements InMemoryDbService{

  createDb() {
    const users: User[] = [
      { id: 'email@email.com', password: 'test' },
      { id: 'gmail@gmail.com', password: 'test' },
      // id represents email here but is necessary, as the web api assumes that every data base
      // has a primary key called id
    ];

    // default returnType
    let returnType  = 'object';
    // let returnType  = 'observable';
    // let returnType  = 'promise';

    switch (returnType) {
      case ('observable'):
        return of({ users }).pipe(delay(10));
      case ('promise'):
        return new Promise(resolve => {
          setTimeout(() => resolve({ users }), 10);
        });
      default:
        return { users };
    }
  }
}

Поскольку я вызываю logUsers () после getUsers () в users.component.ts, я не понимаю, почему пользователи должны быть неопределенными и почему я получаю ошибку. Большое спасибо!

Ответы [ 2 ]

0 голосов
/ 21 февраля 2020
this.getDbDataService.getUsers()
.subscribe((users) => {
  this.users = users;
  this.logUsers();
});
  • Вы пытаетесь получить доступ к пользователям (не определено) без присвоения им значений. Пользователи должны быть инициализированы как []

  • getDbDataService является наблюдаемой, поэтому logUsers () будет вызываться даже до назначения значений пользователям

0 голосов
/ 21 февраля 2020

getUsers при асинхронном вызове. Вам нужно позвонить logUsers в подписке, я изменил код

import { Component, OnInit } from '@angular/core';
import { GetDbDataService} from '../get-db-data.service';
import { User } from '../user';

@Component({
  selector: 'app-users',
  templateUrl: './users.component.html',
  styleUrls: ['./users.component.css']
})
export class UsersComponent implements OnInit {
  users: User[];
  constructor(private getDbDataService: GetDbDataService) { }

  ngOnInit() {
    this.getUsers();

  }

  getUsers(): void {
    this.getDbDataService.getUsers()
    .subscribe(users => {this.users = users;
  this.logUsers();
});
  }

  logUsers(): void{
    this.users.forEach((User) =>{
      console.log("id: " + User.id + " password: " + User.password);
    })
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...