Angular 6 尝试区分“[object Object]”时出错。只允许数组和可迭代对象

Angular 6 Error trying to diff '[object Object]'. Only arrays and iterables are allowed

我认为我的问题是 API 传递的是对象而不是数组。所以我需要将对象修改为数组?

这是怎么做到的? Object.assign ? 还是管道? 有没有人有一个合适的例子? 我还在学习 Angular 这是我的第二个项目,所以我需要一些帮助 ;)

你到目前为止!

这是我的代码

正在从 API 获取数据 ..无法更改 API 它提供一个对象

知识库服务

    import {Injectable, OnInit} from '@angular/core';
    import { HttpClient, HttpErrorResponse, HttpHeaders, HttpRequest, HttpResponse} from '@angular/common/http';
    import {environment} from '../../environments/environment';
    import { WikiModel } from '../../models/wikiItems.model'
    import {catchError, map, take} from 'rxjs/operators';
    import {throwError} from 'rxjs';


    @Injectable()
    export class KnowledgeBaseService {
      wikiApiUrl: string = environment.wikiApiUrl;
      wikiList: WikiModel[] = [];
     constructor(

      protected http: HttpClient,) {}

        getwikiList() {
          return this.http.get(this.wikiApiUrl + "/list")
            .pipe(map((data: any[]) => {return this.wikiList = data;
                }), catchError(error => {
                return throwError('Its a Trap!')
              })
            );
        }
    }

订阅该数据

KnowledgeBaseAdminComponent

    import { Component, OnInit } from '@angular/core';
import { KnowledgeBaseService } from '../../../services/knowledge-base.service';
import { WikiModel } from '../../../../models/wikiItems.model';
import { map, take } from 'rxjs/operators';
import {keyframes} from '@angular/animations';

@Component({
  selector: 'app-knwoledge-center-admin',
  templateUrl: './knowledge-base-admin.component.html',
  styleUrls: ['./knowledge-base-admin.component.scss']
})
export class KnowledgeBaseAdminComponent implements OnInit {

  wikiList: WikiModel[] = [];
  displayDialog: boolean = false;
  editItem: WikiModel = null;

  constructor(private knowledgebaseService: KnowledgeBaseService) {

  }

  ngOnInit() {
    this.getwikiItems()
  }

  getwikiItems(): void {
    this.knowledgebaseService.getwikiList().subscribe(
      data => {
        this.wikiList = data
      },
      err => console.error(err),
      () => console.log('Wiki Items Geladen')
    );
    console.log(this.wikiList)
  }

  showDialogToAdd() {
    this.displayDialog = true;

  }  showDialogToEdit() {
    this.displayDialog = true;
  }
}

维基模型

export class WikiModel {
  title: string;
  text: string;
  keyWords: string;

}

模板 Begriffsdatenbank 概念 Beschreibung 施拉格沃特 {{wikiItems.title}} {{wikiItems.text}} {{wikiItems.keyWords}}

    <div class="ui-g-12">
      <div class="ui-g-4">
        <label for="wikiTitle">Titel</label>
      </div>
      <div class="ui-g-8">
        <input pInputText id="wikiTitle" />
      </div>
    </div>
    <div class="ui-g-12">
      <div class="ui-g-4">
        <label for="wikiText">Wiki Text</label>
      </div>
      <div class="ui-g-8">
          <textarea id="wikiText" [rows]="5" [cols]="35" pInputTextarea ></textarea>
      </div>
    </div>
<!-- TODO: change  textfield to P-chips -->
    <div class="ui-g-12">
      <div class="ui-g-4">
        <label for="wikikeywords">Schlagwörter</label>
      </div>
      <div class="ui-g-8">
        <input pInputText id="wikikeywords" />
      </div>
    </div>
  </div>
</p-dialog>

错误

ERROR Error: Error trying to diff '[object Object]'. Only arrays and iterables are allowed

来自 API 的数据如下所示:

{
  "error": null,
  "status": 200,
  "result": [
    {
      "_key": "338330",
      "_id": "knowbaseItems/338330",
      "_rev": "XIQvCoG--",
      "title": "Test Eintrag",
      "text": "Lalala",
      "keyWords": [
        "test"
      ]
    },
    {
      "_key": "341705",
      "_id": "knowbaseItems/341705",
      "_rev": "XIHSQhy--",
      "title": "Personalpronomen",
      "text": "Fahren Schlitten",
      "keyWords": [
        "ich",
        "du",
        "er"
      ]
    }
  ],
  "code": "200"
}

在你的服务地图中运营商必须returndata.result

getwikiList() {
 return this.http.get(this.wikiApiUrl + "/list")
            .pipe(map((data: any) => data.result ), 
                  catchError(error => { return throwError('Its a Trap!')})
            );
}

像这样更新 p-table

<p-table  [value]="wikiList">
       <ng-template pTemplate="header">
         <tr>
           <th>Begriff</th>
           <th>Beschreibung</th>
           <th>Schlagworte</th>
         </tr>
       </ng-template>
       <ng-template pTemplate="body" let-wikiList>
         <tr>
           <td>{{wikiList.title}}</td>
           <td>{{wikiList.text}}</td>
           <td>{{wikiList.keyWords}}</td>
         </tr>
       </ng-template>
     </p-table>

stackblitz example

请记住,Http 是异步的。这意味着使用此代码:

  getwikiItems(): void {
    this.knowledgebaseService.getwikiList().subscribe(
      data => {
        this.wikiList = data
      },
      err => console.error(err),
      () => console.log('Wiki Items Geladen')
    );
    console.log(this.wikiList)  // <-- ALWAYS UNDEFINED!!
  }

最后 console.log 行将始终 未定义。

流程如下:

1) getwikiList().subscribe 被调用。

2) 执行Http Get请求

3) getwikiList() 方法 returns.

4) 你的 console.log 被执行,此时值未定义。

5) 收到来自 Get 请求的响应。

6) 通知订阅方法中定义的方法并提供数据并设置到this.wikilist.

所以只有在第 6 步之后您才有数据。

如果您想查看您的值,您需要将您的日志记录移动到订阅中,如下所示:

  getwikiItems(): void {
    this.knowledgebaseService.getwikiList().subscribe(
      data => {
        this.wikiList = data;
        console.log(this.wikiList); // <-- here instead
      },
      err => console.error(err),
      () => console.log('Wiki Items Geladen')
    );
  }

您还可以执行以下操作:

getwikiList() {
return this.http.get(this.wikiApiUrl + "/list")
        .pipe(map((data: any) => data.result || [];
            }), catchError(error => {
            return throwError('Its a Trap!')
          })
        );

对我有用