Подлежит наблюдению в массиве * ng за высказывание undefined - PullRequest
0 голосов
/ 07 января 2020

Я новичок в Angular. У меня есть узел и Express бэкэнд, извлекающий данные из базы данных MS SQL. Если я go на URL конечной точки, он отображает мои данные как JSON. Я работаю на локальном хосте, поэтому я установил прокси для CORS. У меня есть класс, который определяет данные, сервис, который извлекает данные из конечной точки, и компонент, который пытается установить массив, равный данным, извлекаемым из сервиса. HTML имеет * ngFor, который должен l oop через значения и отображать их в виде сетки.

Если я вызываю свои данные в моем компоненте через мой сервис, то this.userService.getUsers (), и сделайте console.log. Я вижу набор записей в консоли браузера. Я пытаюсь установить массив равным userService.getUsers (), а затем вызываю массив, и я получаю «неопределенный». Поскольку я новичок, я пытался следовать учебному пособию по Heroes, но это не сработало. Я провел день в поиске в Google и пробовал разные решения, с которыми мне приходилось сталкиваться, но все они выглядят как неопределенные. Я прикреплю код здесь. Если кто-то может мне немного помочь, это было бы очень полезно.

Определение класса пользователя Пользователь:

export class User{
    id: number;
    ccn: string;
    firstName: string;
    lastName: string;
    email: string;
}

Служба пользователя, выполняющая запрос Http:

import { Injectable } from '@angular/core';
import { User } from './user';
import { USERS } from './mock-users';
import { MessageService } from './message.service';
import { Observable, of } from 'rxjs';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { catchError, map, tap } from 'rxjs/operators';

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

  private userURL = 'api/users'
  //private userURL = 'localhost:5000'

  httpOptions = {
    headers: new HttpHeaders({ 'Content-Type': 'application/json' })
  };

  constructor(
    private http: HttpClient,
    private messageService: MessageService) { }

  //getUsers(): Observable<User[]> {
  //  this.messageService.add('UserService: fetched users');
  //  return of(USERS);
  //}

  /** GET users from the server */
  getUsers(): Observable<User[]> {
    //console.log('getting users');
    return this.http.get<User[]>("http://localhost:5000/api/user")
      .pipe(
        tap(_ => this.log('Fetched users')),
        catchError(this.handleError<User[]>('getUsers', []))
      );
      //return this.http.get<User[]>("http://localhost:5000/api/user");
      //console.log('got users');
  }

  /* GET heroes whose name contains search term */
  searchUsers(term: string): Observable<User[]> {
    if (!term.trim()) {
      // if not search term, return empty hero array.
      return of([]);
    }
    return this.http.get<User[]>(`${this.userURL}/?ccn=${term}`).pipe(
      tap(_ => this.log(`found users matching "${term}"`)),
      catchError(this.handleError<User[]>('searchUsers', []))
    );
  }

  addUser (user: User): Observable<User> {
    return this.http.post<User>(this.userURL, user, this.httpOptions).pipe(
      tap((newUser: User) => this.log(`added user w/ id=${newUser.id}`)),
      catchError(this.handleError<User>('addUser'))
    );
  }

  private handleError<T> (operation = 'operation', result?: T) {
    return (error: any): Observable<T> => {
      console.error(error);

      this.log(`${operation} failed: ${error.message}`);

      return of(result as T);
    };
  }

  private log(message: string) {
    this.messageService.add(`User service: ${message}`);
  }
}

Отображение Компонент пользователя TS файл:

import { Component, OnInit } from '@angular/core';
//import { USERS } from '../mock-users';
import { UserService } from '../user.service';
import { User } from '../user';
import { Observable, of } from 'rxjs';
import { catchError, map, tap } from 'rxjs/operators';
import { element } from 'protractor';

@Component({
  selector: 'app-display-users',
  templateUrl: './display-users.component.html',
  styleUrls: ['./display-users.component.css']
})
export class DisplayUsersComponent implements OnInit {
  users: User[] = [];

  constructor(private userService: UserService) { }

  //users$ = this.getUsers();

  ngOnInit() {
    this.getUsers();
    console.log(this.userService.getUsers());
    this.userService.getUsers().forEach(element => {
      console.log(element);
    });
  }

  getUsers(): void {
    /*this.userService.getUsers()
    .subscribe(users => this.users = users);*/
    const userObservable = this.userService.getUsers();
    userObservable.subscribe((userData: User[]) => {
      this.users = userData;
    });
  }

}

Отображение компонента пользователя HTML:

<div class="clr-row">
    <div class="clr-col-lg-11 clr-col-md-11 clr-col-11 main-div">
        <div class="card card-style" style="box-shadow: 0 0 0 0;">
            <div class="card-header">
                <h1><img src="../assets/images/BSOLOGO_gray.png" class="title-img"><span class="title">&nbsp;&nbsp;Users</span></h1>
            </div>
            <div class="card-block">
                <div class="card-title">
                    <clr-datagrid>
                        <clr-dg-column>CCN</clr-dg-column>
                        <clr-dg-column>Last Name</clr-dg-column>
                        <clr-dg-column>First Name</clr-dg-column>
                        <clr-dg-column>Email</clr-dg-column>

                        <clr-dg-row *ngFor="let user of users">
                            <clr-dg-cell>{{user.ccn}}</clr-dg-cell>
                            <clr-dg-cell>{{user.lastName}}</clr-dg-cell>
                            <clr-dg-cell>{{user.firstName}}</clr-dg-cell>
                            <clr-dg-cell>{{user.email}}</clr-dg-cell>
                        </clr-dg-row>

                        <clr-dg-footer>{{users.length}} users</clr-dg-footer>
                    </clr-datagrid>
                </div>
            </div>
        </div>
    </div>
</div>

Любая помощь будет принята с благодарностью!

ОБНОВЛЕНО enter image description here

Ответы [ 3 ]

0 голосов
/ 08 января 2020

Если вам не нужно, чтобы он был Observable, вы можете использовать toPromise (), а использование async / await упрощает процесс

Service

  async getUsers(): Promise<User[]> {
    return await this.http.get<User[]>('http://localhost:5000/api/user').toPromise();
  }

Component.ts

  users: User[] = [];

  async ngOnInit() {
    this.users = await this.userService.getUsers();
  }

Компонент. html

                 <clr-datagrid *ngIf="users">
                    <clr-dg-column>CCN</clr-dg-column>
                    <clr-dg-column>Last Name</clr-dg-column>
                    <clr-dg-column>First Name</clr-dg-column>
                    <clr-dg-column>Email</clr-dg-column>

                    <clr-dg-row *ngFor="let user of users">
                        <clr-dg-cell>{{user.ccn}}</clr-dg-cell>
                        <clr-dg-cell>{{user.lastName}}</clr-dg-cell>
                        <clr-dg-cell>{{user.firstName}}</clr-dg-cell>
                        <clr-dg-cell>{{user.email}}</clr-dg-cell>
                    </clr-dg-row>

                    <clr-dg-footer>{{users.length}} users</clr-dg-footer>
                </clr-datagrid>
0 голосов
/ 09 января 2020

Моя проблема была решена. В моем операторе SQL я вызывал SELECT * FROM table FOR JSON PATH, который создавал странный объект, извлекаемый с сервера. Удаление FOR JSON PATH предоставило данные JSON. Затем второй частью моей проблемы было сопоставление полей моей БД с моим классом пользователя.

Это было сделано так:

    request.query('SELECT * FROM Table ORDER BY myField', function (err, recordset) {
        if (err) console.log(err);    
        const records = recordset.recordset;
        const result = records.map(r => { return { id: r.tableID, field1: r.dbField1, field2: r.dbField2, field3: r.dbField3, field4: r.dbField4}});
        res.send(result);
    });

Надеюсь, это кому-нибудь поможет! Спасибо всем, кто написал мне, чтобы помочь.

0 голосов
/ 07 января 2020

Ypu может заменить getUsers в обоих классах на эти. HTML выглядит хорошо для меня. Я преобразовал пользователей в publi c тоже.

//userService
getUsers(callback: Function) {
    return this.http.get<User[]>("http://localhost:5000/api/user")
      .subscribe(
        response => callback(response)
      );
  }

//Component
public users: User[] = [];
getUsers(): void {
    this.userService.getUsers((result) => {this.users = result;})
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...