Объект представляет собой массив при заполнении таблицы html, но не при повторении в машинописном тексте.

У меня есть серверная база данных, которая обслуживает записи учащихся в виде файлов JSON. Затем эти объекты заносятся в таблицу PrimeNG для отображения и выбора.

student.component.html

<p-table class="table" [columns]="cols" [value]="searchResults">
    <ng-template pTemplate="header" let-columns>
        <tr>
            <th *ngFor="let col of columns">
                {{col.header}}
            </th>
       </tr>
    </ng-template>
    <ng-template pTemplate="body" let-rowData>
        <tr [pSelectableRow]="rowData" class="tr-click" (click)="getSelected(rowData)">
            <td *ngFor="let col of columns">
                {{rowData[col.field]}}
            </td>
        </tr>
    </ng-template>
</p-table>

Однако, когда я пытаюсь прочитать или перебрать записи учащихся в TypeScript, я получаю «TypeError: Cannot read property XXX of undefined».

student.component.ts

export class StudentComponent implements OnInit {

    searchResults: Student[];
    cols: any[];

    constructor(private router: Router, private studentService: StudentService, private http: HttpClient) {

    }

    ngOnInit(): void {
        this.studentService.getStudents().subscribe(data => {
            this.searchResults = data;
        });

        // table columns
        this.cols = [
            { field: 'studentId', header: 'Student ID'},
            { field: 'name', header: 'Name'},
            { field: 'dob', header: 'Date of Birth'},
            { field: 'status', header: 'Status'}
        ];

        // tested the object with these
        alert('1: ' + JSON.stringify(this.searchResults)); // undefined
        alert('2: ' + this.searchResults);                 // undefined
        alert('3: ' + this.searchResults.toString);        // undefined
    }

   // This is what I am trying to accomplish
   getSelected(selected: Student) {
       for (const result of this.searchResults) {
           if (selected.studentID === result.studentID) {
               // do some other stuff
       }
   }
}

Итак, почему таблица PrimeNG может заполнить таблицу объектом, но я не могу выполнить итерацию по ней в TypeScript? Как мне заставить его рассматривать объект как массив?


person sml485    schedule 19.01.2019    source источник
comment
Опубликуйте сообщение об ошибке с указанием имени свойства.   -  person R. Richards    schedule 19.01.2019
comment
alert('1: ' + JSON.stringify(this.searchResults)); не определено, поскольку данные могут быть еще не разрешены. Помните, что наблюдаемый является асинхронным.   -  person Patryk Błaziński    schedule 19.01.2019
comment
Пожалуйста, сократите этот вопрос до минимума, необходимого для объяснения проблемы, включите сообщения об ошибках и предоставьте подробное описание вопроса. Вставка исходного кода и вопрос, почему он не работает, не по теме.   -  person Reactgular    schedule 19.01.2019


Ответы (1)


по-видимому, в вашем файле ts нет объявления columns

<tr [pSelectableRow]="rowData" class="tr-click" (click)="getSelected(rowData)">
    <td *ngFor="let col of columns">
        {{car[col.field]}}
    </td>
</tr>

to

<tr [pSelectableRow]="rowData" class="tr-click" (click)="getSelected(rowData)">
    <td *ngFor="let col of cols">
        {{car[col.field]}}
    </td>
</tr>

Редактировать: вы подписываетесь на асинхронный метод с подпиской, но пытаетесь выполнять назначения после подписки. из-за этого ваша функция не ждет завершения подписки. Решение вашей проблемы:

this.studentService.getStudents().subscribe(data => {
    this.searchResults = data;

     // table columns
    this.cols = [
      { field: 'studentId', header: 'Student ID'},
      { field: 'name', header: 'Name'},
      { field: 'dob', header: 'Date of Birth'},
      { field: 'status', header: 'Status'}
    ];

    // tested the object with these
    alert('1: ' + JSON.stringify(this.searchResults)); // undefined
    alert('2: ' + this.searchResults);                 // undefined
    alert('3: ' + this.searchResults.toString);        // undefined
});
person Derviş Kayımbaşıoğlu    schedule 19.01.2019
comment
Извините, это была опечатка, когда я писал вопрос. - person sml485; 19.01.2019
comment
Итак, каждый метод, работающий с полученными данными (например, мой цикл for), должен вызываться внутри функции подписки? Чтобы убедиться, что они выполняются только тогда, когда данные действительно доступны? - person sml485; 19.01.2019
comment
Если вам нужно дождаться результата, все, что связано с вашей работой, нужно вызывать внутри функции подписки. Если этот ответ полезен для вас, пожалуйста, проголосуйте за него и/или отметьте его как ответ. - person Derviş Kayımbaşıoğlu; 19.01.2019
comment
Спасибо за ответ. Я новичок в angular, и то, как работают подписка и наблюдаемые, сбивает меня с толку. - person sml485; 20.01.2019