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

HolzbeinWilli picture HolzbeinWilli · Jul 17, 2018 · Viewed 23.9k times · Source

I think my Problem is that the API delivers an Object instead of an array. So i need to Modify the Object to be an Array ?

How could this be done ? Object.assign ? Or Pipe ? Does anyone have a proper example ? I'am still learning Angular this is my second Project so i need some help ;)

thy so far !

Here is my code

getting data from API ..cant change the API it delivers an Object

KnowledgeBaseService

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

subscribe to that Data

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

WikiModel

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

}

Template Begriffsdatenbank Begriff Beschreibung Schlagworte {{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: Error trying to diff '[object Object]'. Only arrays and iterables are allowed

The Data from the API looks like:

{
  "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"
}

Answer

malbarmavi picture malbarmavi · Jul 17, 2018

In your service map operator must return data.result

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

Just update p-table like this

<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 🚀