fail reading object type of json - html

i have an Object type of json that I cant read...
this is my json:
body: {
"111": {
"name": "name1",
"status": 10000
},
"222": {
"name": "name2",
"status": 20000
},
"333": {
"name": "name3",
"status": 30000
}
}
and I want to know how to present it in my html?
this is my attempt:
<md-content>
<h1 align="center">{{title}}</h1>
<h2>list of items:</h2>
<div class="list-bg" *ngFor="#item of items | async">
ID: {{item.name}} <p></p> Number of Items: {{item.status}}
</div>
</md-content>
not only that it dosent work, im trying to figure out how to read each line the object id's(those: 111, 222, 333)
this is my model:
export interface MyModel {
name: string;
status: number;
}
this is my component:
export class MyCmp implements OnInit {
retJson: Observable<MyModel[]>
constructor(private _myService: MyService) {};
public showData(): void {
this.retJson = this._myService.getData();
}
}
thanks!

You haven't included how you load your json, so I'll write a more general example:
interface MyModel {
name: string;
status: number;
}
interface MyResponse {
body: { [id: string]: MyModel }
}
let response: MyResponse = JSON.parse(RESPONSE_STRING);
Object.keys(response.body).forEach(id => {
let model = response.body[id];
console.log(`id: ${ id }, name: ${ model.name }, status: ${ model.status }`);
});
What's missing here is the RESPONSE_STRING, which I'm not sure how you get.
As for the template, I'm not an angular developer but as far as I understand ngFor is used for arrays, and you don't have an array in your json structure.

ngFor loop only will work for array. Your body json is key value object, so it wouldn't work.
If you want to make it work, it's either:
you use an additional pipe to convert key value object to array using pipe, solution discussed here: Iterate over TypeScript Dictionary in Angular 2, then you can use
*ngFor="let item of items | async | mapToIterable"
Or process it in your ts file, instead of
this.retJson = this._myService.getData();, use this._myService.getData().subscribe(x => this.retJson = processToArray(x))

Related

How to set json file to object's array in Angular

how to set json file to my "Client" object's array?
I have json, which looks like this:
Clients.json
{
"clients": [
{
"firstName": "nameA",
"lastName": "lastA",
"doctorsName": "domm",
"procedure": "consultation",
"registrationDate": "new Date(2019, 10, 12)",
"isAlreadyServed": "false"
},
{
"firstName": "nameB",
"lastName": "lastB",
"doctorsName": "domm",
"procedure": "procedureA",
"registrationDate": "new Date(2019, 10, 12)",
"isAlreadyServed": "false"
},
{
"firstName": "nameC",
"lastName": "lastC",
"doctorsName": "doctorA",
"procedure": "procedureC",
"registrationDate": "new Date(2019, 10, 12)",
"isAlreadyServed": "false"
},
...
...
...
And how can I set it to object's array Client.service.ts
clients: Client[] = this.http.get('path.Clients.json') // ??
Since your data is in the client-side as a JSON file. Though you can use HttpClient, here is another solution for the same.
You can directly import the JSON as a constant and assign it to clients as of TS 2.9 (docs).
import Clients from 'path/to/client/json';
clients: ClientsJson = Clients;
where the ClientsJson interface would look like this.
export interface ClientsJson {
clients: Client[];
}
export interface Client {
firstName: string;
lastName: string;
doctorsName: string;
procedure: string;
registrationDate: Date;
isAlreadyServed: boolean;
}
Here is a working example on StackBlitz.
You first need to define an interface that matches your object structure:
public interface ClientConfiguration {
firstName: string;
lastName: string;
doctorsName: string;
// And so on...
}
Then, just like the code you have shown, you need to type the http.get method in order to obtain the correct output.
public getConfiguration(): Observable<Array<ClientConfiguration>> {
return this.http.get<Array<ClientConfiguration>>('path/to/client/json');
}
Since my getConfiguration() method returns an observable, you will need to subscribe to it in your components or services:
#Component({ ... })
export class MyComponent implements OnInit {
public ngOnInit(): void {
this.getConfiguration().subscribe(result: Array<ClientConfiguration> => {
this.clientConfiguration = result;
});
}
public getConfiguration(): Observable<Array<ClientConfiguration>> {
return this.http.get<Array<ClientConfiguration>>('path/to/client/json');
}
}
You can read more here about HttpClient at Angular's official documentation: https://angular.io/guide/http
Hope it helps.

How can I display last property in a JSON object first in the UI

I have a JSON of following format:
[
{Details: [{name: "WII", type:"Video Games", id:"lint"}]
]
however on the UI in a table, I want to display ID first in the first column followed by the others.
Let's assume this is your JS data structure:
let list = [
{ Details: [{ name: "WII", type: "Video Games", id: "lint" }] }
];
Then in your Angular component template:
<table>
<tr *ngFor="let item of list" >
<td>{{item.Details[0].id}}</td>
<td>{{item.Details[0].name}}</td>
<td>{{item.Details[0].type}}</td>
</tr>
</table>
Of course, this is not ideal but to give you a better answer/solution you should provide more information.
You can make use of Pipe to get the keys and reverse it.
import { PipeTransform, Pipe } from '#angular/core';
#Pipe({name: 'keys'})
export class KeysPipe implements PipeTransform {
transform(value, args:string[]) : any {
let keys = [];
for (let key in value) {
keys.push(key);
}
return keys.reverse();
}
}
STACKBLITZ DEMO

Parsing JSON items using Angular

I have a JSON object and I want to give the values of the properties to 4 of my variables using Angular, which are the following:
authorText : string;
titleText : string;
durationText : string;
genreText : string;
And here is the JSON:
"{"n":{
"_id":1101,
"labels":[
"Song"
],
"properties":{
"duration":"214000",
"author":"Shawn Mendes",
"genre":"pop",
"title":"In My Blood"
}
}
}"
I tried using this and similar solutions to this:
Object.keys(editData).forEach(function (key) {
console.log(key);
if(key === "author"){
this.authorText = editData[key];
}
console.log( key , editData[key] );
});
But the key is always 0 for some reason.
EDIT
Added the image of the JSON:
The string I printed before was done as following : Saving it as global variable and then using JSON.stringify(temp1);.
You can use this:
const { duration, author, genre, title } = this.editData[0].n.properties;
this.song = {
authorText: author,
titleText: title,
durationText: duration,
genreText: genre
};
Here, we're destructuring the properties from the properties key and just assigning them to the song Object's keys one by one.
A better thing to do would be just to name the fields as duration, author, genre, and title. Then you can simply do something like this:
export interface Song {
author: string;
title: string;
duration: string;
genre: string;
}
And in your function:
this.song = { ...editData[0].n.properties };
Here, we're using the spread operator(...) to spread the properties object's keys and assign them to the song property on your Component Class.
Here's a Sample StackBlitz for your ref.
You can just do this:
this.song = this.editData.n.properties;
I have a stackblitz demonstrating it here: https://stackblitz.com/edit/angular-udmdqr
The basic code is here:
import { Component, Input } from '#angular/core';
#Component({
selector: 'hello',
template: `<h1>Hello {{song.author}}!</h1>`,
styles: [`h1 { font-family: Lato; }`]
})
export class HelloComponent {
song: Song;
editData = {
"n": {
"_id": 1101,
"labels": [
"Song"
],
"properties": {
"duration": "214000",
"author": "Shawn Mendes",
"genre": "pop",
"title": "In My Blood"
}
}
}
constructor() {
this.song = this.editData.n.properties;
}
}
export interface Song {
duration: string;
author: string;
genre: string;
title: string
}

Typescript, Angular 2 - Parse Json to object in http

I have a file location.json, containing JSON string of the form:
{
"locations": [
{
"id": 1,
"places": [
{
"id": 1,
"city": "A",
"state": "AB"
}
]
}
}
I created classes of the form:
export class Location{
constructor(public id: number,
public places: Place[],
}
export class Place {
constructor(
public id: number,
public city: string,
public state: string
}
How do I parse the JSON string to object? I did something like this:
...
export class DashboardComponent {
locations: Locations[];
constructor(private locationService:LocationService) {
this.getLocations()
}
getLocations(){
this.locationService.get('assets/location.json')
.subscribe(res => this.location = res);
}
Depending on what's the result for the subsriber it can be:
.map(res => this.location = res.json().locations);
Or:
.subscribe(res => this.location = JSON.parse(res).locations);
But keep in mind that that won't instiantiate instances for your classes, it will only assign the values as regular js object which match the following:
interface Location {
id: number;
places: Place[];
}
interface Place {
id: number;
city: string;
state: string;
}
If you want instances of the classes you'll need to do something like:
JSON.parse(res)
.locations.map(location => new Location(location.id,
location.places.map(place => new Place(place.id, place.city, place.state)))
usually you map response with res => res.json() somewhere in the service method but json should have a valid format, otherwise it won't parse.
Note, that response is an Object and you can't parse it but only body of the response.
return this.http.get(url,options).map((response) => this.parseResponse(response))
.catch((err) => this.handleError(err));
private handleError(error: any) {
let body = error.json();
return Observable.throw(body);
}
private parseResponse(response: Response) {
return response.json();
}

Angular2 Getting very deep nested json value using pipe! *ngFor

Hi I am having trouble getting json value which is really deeply nested using pipe.
What am I doing wrong?
Pipe I'm using
import { Pipe, PipeTransform } from '#angular/core';
#Pipe({
name: 'keyValues'
})
export class KeysPipe implements PipeTransform {
transform(value, args: string[]): any {
let keys = [];
for (let key in value) {
keys.push({
key: key,
value: value[key]
});
}
return keys;
}
}
Json I'm getting from server.
data:
0: {
Profile: { ...
}
BasicInfo: { ...
}
introduceInfo: {
curriculum: { ...
}
experience: {
0: {
category: "Mentor"
year: "2011"
duration: "24"
}
1: {
category: "Student"
year: "2011"
duration: "14"
}
}
}
}
It's actually a huge json object but I've simplified to only show what I need to get.
I want to get the value of category (which is "Mentor"and "Student".
And to do so, I've tried in my html
<div *ngFor="let detail of teaInfo | keyValues">
<div *ngFor="let experience of detail.value['introduceInfo'] | keyValues">
<div *ngFor="let exp of experience.value['experience'] | keyValues">
<p class="fontstyle2">{{exp.value['category']}} {{exp.value['year']}}년 | {{ex.value['duration']}}개월</p>
</div>
</div>
</div>
And I'm getting my json object in my component like this.
teaInfo: any[];
getTeacherDetail(): void {
let params = new URLSearchParams();
params.set('gradeType', `${this.getVal2()}`)
params.set('subjectType', `${this.getVal3()}`)
params.set('district', `${this.getVal1()}`)
this.teaDetail.getTeachersDetail(params)
.subscribe(
teaInfo => this.teaInfo = teaInfo,
error => this.errorMessage = error
)
}
And the result is I am getting nothing
What am I doing wrong?
Trying to interpret how your JSON looks like, something like this:
{
"data":{
"0": {
"Profile":{
"prof":"prof"
},
"BasicInfo":{
"basic":"basic"
},
"introduceInfo":{
"curriculum": {
"curr":"curr"
},
"experience":{
"0":{
"category":"Mentor",
"year":"2011",
"duration":"24"
},
"1":{
"category":"Student",
"year":"2011",
"duration":"14"
}
}
}
}
}
}
In below example, I have extracted the values from data, so:
.map(res => res.json().data)
To reach values Mentor and Student, first change your pipe to this:
export class KeysPipe implements PipeTransform {
transform(value: any, args: any[] = null): any {
return Object.keys(value).map(key => value[key]);
}
}
and change your HTML to this:
<div *ngFor="let detail of teaInfo | keyValues">
<div *ngFor="let experience of detail['introduceInfo']['experience'] | keyValues">
{{experience.category}}
</div>
</div>
This should work nicely:
Demo