Deserialize of an API response and display it in view loop - html

I have a problem with response deserialization. What is the best way to deserialize data to projects and display it in view in the simplest way? My IDE doesn't find map() method.
Response:
{
"totalCount": 2,
"items": [
{
"title": "TestProject1",
"id": 1
},
{
"title": "TestProject2",
"id": 2
}
]
}
Typescript:
private usertoken: string;
private projects: any;
constructor(private http: HttpClient, private cookie : CookieService) { }
ngOnInit() {
this.usertoken = this.cookie.get('usertoken');
console.log("asdasdasd1");
this.http.get("https://localhost:5001/api/abc/cba",
{headers: new HttpHeaders().set('Authorization', 'Bearer ' + this.usertoken)})
.subscribe(data =>{
this.projects = data;
});
Html:
<table>
<tr *ngFor="let project of projects">
<th scope="row">{{ project.totalCount }}</th>
<!-- <td>{{ project.projectName }}</td> -->
</tr>
</table>

As #Nico suggested, you are iterating the wrong object. If you set the data directly in the projects, you have the projects.Items and project.TotalCount, so you should make the for in the Items which is the array.
<tr *ngFor="let project of projects.items">
<th scope="row">{{ projects.totalCount }}</th> //Get total Count from the main object
<td>{{ project.title }}</td> //Get name from the items interaction
</tr>

Related

Why I cannot see json data in table?

I am trying to display json data in tree hierachy table with vue.js. Unfortunally I cannot see any data inside of the table. The path is correct, I have checked this by URL adress, the format as well. My goal is to create tree hierarchy table, with action button for removing layers. I would like to mention thath I am new in Vue.js framework, so this is not maybe the best option how to work with fetched data from json file.
HTML:
<table>
<thead>
<tr>
<th>Name</th>
<th>Parent</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr v-for="item in items" :key="item.id">
<td>{{ item.name }}</td>
<td>{{ item.parent }}</td>
<td>
<button #click="toggleChildren(item)">Toggle Children</button>
</td>
<template v-if="item.childrenVisible">
<tr v-for="child in item.children" :key="child.id">
<td>{{ child.name }}</td>
<td>{{ child.parent }}</td>
<td>
<button #click="toggleChildren(child)">Toggle Children</button>
</td>
</tr>
</template>
</tr>
</tbody>
</table>
</div>
Vue.js code
<script>
fetch('data/vue-data.json')
.then(response => response.json())
.then(data => {
new Vue({
el: '#app',
data: {
items: data.items
},
methods: {
toggleChildren(item) {
item.childrenVisible = !item.childrenVisible;
},
}
});
})
</script>
you create your app in advance. also where is your #app container?
<div id="app">
<!-- your table data -->
</div>
and for the js
new Vue({
el: '#app',
// data should return an object, not be an object
data() {
return {
items: [] // default value, could also be null
}
},
// called on initialization, read about lifecycle hooks
mounted() {
fetch('data/vue-data.json').then(response => { this.items = response.json() })
},
methods: {
toggleChildren(item) {
item.childrenVisible = !item.childrenVisible;
},
}
});

Put json data into table

I actually want to create a table with the data who the api return to me.
The problem is that i can't print the data.
The IdLangage have his column in the table and i want to put the data of the traduction into the correct cell.
The JSON data format :
traductionData ={
"Data":
[
{
"Code": "BJR",
"TraductionsFormat":
[{
"Code": "BJR",
"Description": null,
"Id": 0,
"IdLangage": "FR",
"Traduction": "Bonjour"
},
{
"Code": "BJR",
"Description": null,
"Id": 0,
"IdLangage": "EN",
"Traduction": "Hello"
}]
},
] };
Here is my table where i want to print the data into :
<table>
<thead>
<tr>
<th width="25%">Code</th>
<th width="15%">FR</th>
<th width="15%">EN</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let traduction of traductionData">
<td>{{ traduction.TraductionsFormat.Code }}</td>
<td>{{ traduction.TraductionsFormat.Traduction}}</td>
</tr>
</tbody>
</table>
Here is my angular service :
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http'
import { map } from 'rxjs/operators';
import { environment } from 'src/environments/environment';
#Injectable({
providedIn: 'root'
})
export class ApiService {
localUrlAPI: string = environment.urlAPI;
constructor(private http : HttpClient) { }
getAllTraductions(){
return this.http.get<any>(this.localUrlAPI+"GetAllTraductionsGroupByCode")
.pipe(map((res:any)=>{
return res;
console.log(res);
}))
}
}
And here is my angular Component with my http request :
import { Component, OnInit } from '#angular/core';
import { ApiService } from 'src/app/services/api.service';
#Component({
selector: 'app-grid-edit-traductions',
templateUrl: './grid-edit-traductions.component.html',
styleUrls: ['./grid-edit-traductions.component.scss']
})
export class GridEditTraductionsComponent implements OnInit {
traductionData !: any[];
constructor(private api: ApiService) { }
ngOnInit(): void {
this.getLesTraductions();
}
getLesTraductions(){
this.api.getAllTraductions()
.subscribe(res=>{
this.traductionData = res.Data;
console.log(this.traductionData)
})
}
}
<table>
<thead>
<tr>
<th *ngFor="let column of tableHeaders">
{{column}}
</th>
</tr>
</thead>
<tbody>
<tr ng *ngFor="let row of tableRows">
<td *ngFor="let column of tableHeaders">
{{row[column]}}
<ng-container *ngFor="let trad of row.TraductionsFormat, let j = index">
<span *ngIf="row.TraductionsFormat[j].IdLangage === column">
{{row.TraductionsFormat[j].Traduction}}
</span>
</ng-container>
</td>
</tr>
</tbody>
</table>
Here's the ts:
tableRows: Array<any> = [];
tableHeaders: Array<any> = [];
ngOnInit(): void {
//---- TABLE HEADERS -----
this.tableHeaders.push("Code")
this.traductionData.Data.forEach(el => {
el.TraductionsFormat.map(c => c.IdLangage).forEach(lang => {
this.tableHeaders.push(lang);
})
});
this.tableHeaders = [...new Set(this.tableHeaders)];
//---- TABLE ROWS -----
this.traductionData.Data.forEach(el => {
this.tableRows.push(el)
});
}
Stackblitz example
The JSON data you've provided is wrong, there are missing commas and brackets. Although, I'm pretty sure that the reason the data isn't shown in table is that the "TraductionsFormat" is an array. If you want to get an item from array you have to provide an index.
<tr *ngFor="let traduction of traductionData">
<td>{{ traduction.TraductionsFormat[0].Code }}</td>
<td>{{ traduction.TraductionsFormat[0].Traduction}}</td>
</tr>
Above is just simple solution. You might want to use dynamic indexes.

error TS2571: Object is of type 'unknown' when try pipe slice in *ngFor

I trying to use NGB Pagination on my angular app in a table. But when i use pipe slice in my *ngFor, my Angular appear error TS2571: Object is of type 'unknown' when try slice. This is my code:
My HTML code:
<tr *ngFor="let row of documentaryList|slice: (page-1) * pageSize : page * pageSize" class="text-md text-md-center">
<td>{{ row.documentDate }}</td>
<td><a class="text-info" routerLink="details-documentary/{{row._id}}">{{ row.documentName }}</a></td>
<td>{{ row.documentNumber }}</td>
<td>{{ row.documentType }}</td>
<td>{{ row.documentAddress }}</td>
<td>
My .ts code:
export class ListDocumentaryComponent implements OnInit {
title = 'Documentary';
documentaryList: any;
page = 1;
pageSize = 10;
lengthDocumentList = 0;
constructor(private documentaryService: DocumentaryService) {
}
ngOnInit(): void {
this.getDocumentaryList();
}
getDocumentaryList(): any {
this.documentaryService.getDocumentary()
.subscribe((data: any) => {
this.documentaryList = data.data;
this.lengthDocumentList = this.documentaryList.length;
});
}
}
My Object in console:
And my Error:
Thanks for your help!
Change documentaryList: any; to documentaryList: any[] = [];

How to print JSON values with keys starting with special characters using angular?

When I try to print using #place it throws error while the other keys are accessible.
[{
"ID": "001",
"Name": "Eurasian Collared-Dove",
"Type": "Dove",
"Scientific Name": "Streptopelia",
"#place": "New York"
}]
This is the error I am getting:
Parser Error: Unexpected token Lexer Error: Unexpected character [#] at column 6 in expression [bird.#place], expected identifier or keyword at column 7 in [{{bird.#place}}]
The component.ts file is as follows:
import { Component } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { HttpErrorResponse } from '#angular/common/http';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'JSON to Table ';
constructor (private httpService: HttpClient) { }
arrBirds: string [];
ngOnInit () {
this.httpService.get('./assets/birds.json').subscribe(
data => {
this.arrBirds = data as string []; // FILL THE ARRAY WITH DATA.
// this.arrService = JSON.stringify(data);
console.log(this.arrBirds);
},
(err: HttpErrorResponse) => {
console.log (err.message);
}
);
}
}
The component.html file is like this:
<table *ngIf="arrBirds">
<tr>
<th>ID</th>
<th>Name of Bird</th>
<th>Type of Bird</th>
<th>Place</th>
</tr>
<tr *ngFor="let bird of arrBirds">
<td>{{bird.ID}}</td>
<td>{{bird.Name}}</td>
<td>{{bird.Type}}</td>
<td>{{bird.#place}}</td>
</tr>
</table>
As noted in my comment, you could use the bracket notation instead of the dot notation.
<tr *ngFor="let bird of arrBirds">
<td>{{ bird['ID'] }}</td>
<td>{{ bird['Name'] }}</td>
<td>{{ bird['Type'] }}</td>
<td>{{ bird['#place'] }}</td>
</tr>
Working example: Stackblitz
In HTML I don't know any other method to call a property. The only solution I can see is to do a getter.
In TS
get place() {
return bird['#Place']
}
In HTML
{{ place }}

Looping over JSON array using *ngFor

I currently have the following JSON file:
[
{
"Arsenal": {
"form": {
"away": 4.6064800860172,
"home": 2.2108841763771
},
"stadium": "Stadium 1"
}
},
{
"Man City": {
"form": {
"away": 4.9473459270023,
"home": 5
},
"stadium": "Stadium 2"
}
},
{
"Man Utd": {
"form": {
"away": 5,
"home": 3.2296790061981
},
"stadium": "Stadium 3"
}
}
]
and I want to display this data in a table. I currently have a service that retrieves the JSON file and returns it
public getJSON(): Observable<any> {
return this.http.get('assets/teams.json')
.map(
(response: Response) => {
const data = response.json();
return data;
}
);
}
I then subscribe to it in my component and save it to teams.
teams = [];
loadJSON() {
this.teamService.getJSON().subscribe(
(teams: any[]) => this.teams = teams,
(error) => console.log(error)
);
}
and using the following HTML
<div class="container">
<table class="table">
<thead>
<tr>
<th>Team</th>
<th>Home</th>
<th>Away</th>
<th>Stadium</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let team of teams | keys">
<td>{{ (team.value | keys)[0].key }}</td>
<td>{{ (team.value | keys)[0].value["form"]["home"] }}</td>
<td>{{ (team.value | keys)[0].value["form"]["away"] }}</td>
<td>{{ (team.value | keys)[0].value["stadium"] }}</td>
</tr>
</tbody>
</table>
</div>
gives the table seen below
Surely there must be a better way of doing this? How can I do this in a more straight-forward way, that is a lot more readable? For example, if the key was actually "Arsenal", "Man City" and "Man Utd" instead of 0, 1 and 2 respectively, it would be much more readable. Why does it have those keys instead? I'm used to coding in Python so it doesn't really make much sense to me.
A working stackblitz can be found here.
I propose to have your own Team object and map your JSON on it.
So in your teams.service you have:
public getJSON(): Observable<Team[]> {
return this.http.get('assets/teams.json')
.map(teams => teams.map(team => this.mapTeam(team)))
}
private mapTeam(res: any): Team {
const teamName = Object.keys(res)[0]
return new Team(
teamName,
{away: res[teamName].form.away, home: res[teamName].form.home},
res[teamName].stadium
)
}
Your Team class can be like this:
export class Team {
constructor(public name: string,
public form: { away: number, home: number },
public stadium: string) {
}
}
It's not the subject of your question but in this the Team class it's preferable to have private properties and have getter to access it.
In your component.ts:
Just call your service and assign the value of the subscribe: this.teamService.getJSON().subscribe(value => this.teams = value)
There are antother way to do this part but it's not your question too
And finally your html it's more readable:
<div class="container">
<table class="table">
<thead>
<tr>
<th>Team</th>
<th>Home</th>
<th>Away</th>
<th>Stadium</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let team of teams">
<td>{{ team.name }} </td>
<td>{{ team.form.home }}</td>
<td>{{ team.form.away }}</td>
<td>{{ team.stadium }}</td>
</tr>
</tbody>
</table>
</div>
The stackblitz here: https://stackblitz.com/edit/angular-gwj6nb