Reputation: 198
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 ..can't 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
<div class="section section-wiki-admin-head">
<h1 class="h-centered">Begriffsdatenbank</h1>
</div>
<div class="section section-wiki-admin-table">
<div class="wiki-articles-table-container">
<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" *ngFor="let wikiItems of wikiList">
<tr>
<td>{{wikiItems.title}}</td>
<td>{{wikiItems.text}}</td>
<td>{{wikiItems.keyWords}}</td>
</tr>
</ng-template>
</p-table>
</div>
</div>
<div class="section section-wiki-admin-footer">
<div class="wiki-articles-table-toolbar">
<button pButton id="wiki-a-new" class="ui-button-success wiki-a-footer-btn" type="button" icon="fa fa-plus" (click)="showDialogToAdd()" label="Neu"></button>
<button pButton id="wiki-a-edit" class="ui-button-info wiki-a-footer-btn" type="button" icon="fa fa-edit" (click)="showDialogToEdit()" label="Bearbeiten"></button>
<button pButton class="ui-button-danger wiki-a-footer-btn" type="button" icon="fa fa-trash" label="Löschen"></button>
</div>
</div>
<p-dialog [header]="editItem && editItem? 'Bearbeiten' : 'Hinzufügen'" [(visible)]="displayDialog" [responsive]="true" showEffect="fade" [modal]="true" [width]="600">
<div class="ui-g ui-fluid">
<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"
}
Upvotes: 11
Views: 51907
Reputation: 1
Look careful with your data coming from your api. If you use model class only those elements define in model class access.so make your you add data.result and then pass into another object
For e.g this.wikiList = data.result In html ngFor = "let wikilist of wikiList"
Upvotes: 0
Reputation: 71
You can also do the below:
getwikiList() {
return this.http.get(this.wikiApiUrl + "/list")
.pipe(map((data: any) => data.result || [];
}), catchError(error => {
return throwError('Its a Trap!')
})
);
It worked for me
Upvotes: 2
Reputation: 24424
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>
Upvotes: 13
Reputation: 60528
Keep in mind that Http is asynchronous. That means with this code:
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!!
}
The last console.log line will always be undefined.
The flow is as follows:
1) The getwikiList().subscribe is called.
2) The Http Get request is executed.
3) The getwikiList() method returns.
4) Your console.log is executed and the value is undefined at this point.
5) A response is received from the Get request.
6) The method defined within the subscribe method is notified and the data is provided and set to the this.wikilist.
So it is only after step 6 that you have the data.
If you want to see your values, you need to move your logging within the subscribe as shown below:
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')
);
}
Upvotes: 4