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

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

Related

Print Json Data in HTML with Ionic/Angular

I'm building an app with IONIC Angular, and I'm trying to print the result in HTML.
From console.log it works correctly, but from the view I can't get the data printed
json api
{
"matches1": {
"homeTeam": "Barcellona",
"awayTeam": "Real Madrid",
},
"matches2": {
"homeTeam": "PSG",
"awayTeam": "Lione",
}
}
home.page.ts
export class HomePage {
matches1: any;
homeTeam1: any;
awayTeam1: any;
result1: any;
private apiurl = 'https://myapi.xxx';
constructor(private httpService: HttpClient) {
this.getdata();
}
getdata() {
this.httpService.get(this.apiurl).subscribe(res => {
this.item = res['matches1']['homeTeam'];
console.log(this.item); <-- this work in console log
}, (err: HttpErrorResponse) => {
console.log (err.message);
}
);
}
}
home.page html
<ion-item *ngFor="let item of items">
{{item.homeTeam}}
</ion-item>
thanks!
This should do the work :
export class HomePage {
matches1: any;
homeTeam1: any;
awayTeam1: any;
result1: any;
items: any;
private apiurl = 'https://myapi.xxx';
constructor(private httpService: HttpClient) {
this.getdata();
}
getdata() {
this.httpService.get(this.apiurl).subscribe(res => {
this.items = Object.keys(res).map(function(key, index) {
return res[key];
});
}, (err: HttpErrorResponse) => {
console.log (err.message);
}
);
}
}
I like to use the json pipe (https://angular.io/api/common/JsonPipe), try this:
<pre>{{ items | json }}</pre>
Edit:
In your case, it might be item | json. Also, Hala Madrid !
You need to declare item in your Controller, and you can't use ngFor if your item is not a list. Right now your json is NOT returning an array, so if you can, it would be best to make it into a list of matches.
Your Json would look better if it was something like this:
{
"matches": [
{
"homeTeam": "Barcellona",
"awayTeam": "Real Madrid",
},
{
"homeTeam": "PSG",
"awayTeam": "Lione",
}
]
}
This way you can easily iterate through your list of matches in your controller
export class HomePage {
matches1: any;
homeTeam1: any;
awayTeam1: any;
result1: any;
item: string[]:
private apiurl = 'https://myapi.xxx';
constructor(private httpService: HttpClient) {
this.getdata();
}
getdata() {
this.httpService.get(this.apiurl).subscribe(res => {
res["matches"].forEach(match => this.item.push(match["homeTeam"]));
}, (err: HttpErrorResponse) => {
console.log (err.message);
}
);
}
}

How to access the nested jsondata in angular template, i have tried this using ngFor doesn't work for me

I am trying to access the JSON data inside my angular template but I have no idea how to do it:
JSON DATA:
{
"data": {
"active_cryptocurrencies": 2050,
"active_markets": 15110,
"bitcoin_percentage_of_market_cap": 53.85,
"quotes": {
"USD": {
"total_market_cap": 207937227143.0,
"total_volume_24h": 10373130891.0
}
},
"last_updated": 1540293278
},
"metadata": {
"timestamp": 1540292653,
"error": null
}
}
mycomponent.ts
jsonData: any[];
private _url = 'https://api.coinmarketcap.com/v2/global/';
constructor(private http: Http) {
http.get("https://api.coinmarketcap.com/v2/global/")
.subscribe(response =>{
this.jsonData = response.json().data.quotes;
console.log(this.jsonData);
});
}
So I am trying to show these details in the angular template but it says cannot
find-a-differ-supporting-object-object-object-of-type-object-ngfor
Can you please help me as to how to go with this as json here is little messy?
I simply want to show the JSON data in my html template.
Edited:
import { Component, Input, OnInit,Injectable } from '#angular/core';
import { Http, Headers } from '#angular/http' ;
#Component({
selector: 'hello',
template: `
Hello, Angular
<ul *ngFor="let item of data">
<li>active_markets :{{item.active_markets}}</li>
<li>bitcoin_percentage_of_market_cap:{{item.bitcoin_percentage_of_market_cap}}</li>
<li>last_updated: {{item.last_updated}} </li>
<li>
<ul *ngFor="let q of item.quotes">
<li>total_market_cap: {{q.total_market_cap}}</li>
<li>total_volume_24h: {{q.total_volume_24h}}</li>
</ul>
</li>
</ul>
`,
styles: [`h1 { font-family: Lato; }`]
})
export class HelloComponent {
#Input() name: string;
data:any=[];
private _url = 'https://api.coinmarketcap.com/v2/global/';
constructor(private http: Http) {}
async ngOnInit(){
let obj =(await this.http.get(this._url).toPromise()).json();
you should convert your json object
this.data= Object.keys(obj).map(function(e){
Object.keys(obj[e]).forEach(function(k){
if(typeof obj[e][k] == "object" && (obj[e][k]!=undefined || obj[e][k]!=null )) {
obj[e][k] = Object.keys(obj[e][k]).map(function(l){
return obj[e][k][l];
});
}
}return obj[e];
});
);}}

How do I display that JSON in Angular2

How do I display this specific JSON using *ngFor?
{
"status": 0,
"dallases": [{
"vehicle_id": 17954,
"dallassettings": "3",
"dallasupdated": "False",
"dallas_list": [{
"number": 666111222,
"auth": 3
}, {
"number": 666777888,
"auth": 4
}, {
"number": 123454321,
"auth": 4
}]
}
}
vehicle.service.ts
import { Injectable } from '#angular/core';
import { Http, Headers, RequestOptions, Jsonp, Response } from '#angular/http';
import 'rxjs/add/operator/map';
#Injectable()
export class VehicleService {
constructor(private http: Http) { }
getVehicle() {
return this.http.get('myURL')
.map(res => res.json());
}
}
vehicle.component.ts
import { Component, enableProdMode } from '#angular/core';
import { VehicleService } from './vehicle.service';
enableProdMode();
#Component({
//moduleId: module.id,
selector: 'vehicle-json',
templateUrl: './vehicle.html',
providers: [VehicleService]
})
export class VehicleComponent {
//vehicles: Vehicle[];
vehicles: GeneralVehicle[];
constructor(private vehicleService: VehicleService) {
this.vehicleService.getVehicle().subscribe(vehicle => {
this.vehicles = vehicle;
});
}
}
/*interface Vehicle {
id: number;
title: string;
body: string;
}*/
interface GeneralVehicle {
status: number;
dallases: Vehicle[];
}
interface Vehicle {
vehicle_id: number;
dallassettings: number;
dallasupdated: string;
dallas_list: DallasList[];
}
interface DallasList {
number: number;
auth: number;
}
When I worked on dummy data it was simply, but this JSON structure is more complex. I tried using Pipe, but I'm not sure if I'm using it correctly.
import { Pipe, PipeTransform } from '#angular/core';
#Pipe({ name: 'keys' })
export class VehiclePipe implements PipeTransform {
transform(value, args: string[]): any {
let keys = [];
for (let key in value) {
keys.push(key);
}
return keys;
}
}
That's the *ngFor
*ngFor="let vehicle of vehicles | keys"
I'd like to dislay status once, and then repeat all the dallases (Vehicle[]).
At least you have one error here:
dallassettings: '3' // string
but in your interface you have:
dallassettings: number;
Then if you implement Matthiases implementation, put a *ngIf-statement, since I suspect you get your data async, so view is rendered before data retrieved, which would cause a undefined error.
<div *ngIf="vehicles"> // here!
<h1>{{ vehicles.status }}</h1>
<div *ngFor="let vehicle of vehicles.dallases">
<div>ID: {{vehicle.vehicle_id}}</div>
<div>Settings: {{vehicle.dallassettings}}</div>
<div>Updated: {{vehicle.dallasupdated}}</div>
<div *ngFor="let d of vehicle.dallas_list">
<div>number: {{d.number}}</div>
<div>auth: {{d.auth}}</div>
</div>
</div>
</div>
EDIT your status is undefined, since you you are using the wrong attribute it should be vehicles.status with "s". When I edited this post, I also added the "s" to the answer, so that it would be correct :)
You have to loop through 2 ngFor's:
<div *ngFor="let vehicle of vehicles | keys">
<h1>{{ vehicle.status }}</h1>
<ul *ngFor="let dallas of vehicle.dallases">
<li>{{ dallas | json }}</li> //Show the data you want
</ul>
</div>
vehicles is an object. I see no need to iterate over the keys with the pipe you proposed. You can access the members you need directly. You should iterate over the dalasses property of vehicles - which is an array. Then display the array member as you require. E.g. with a json pipe to get in text format, you you might also implement custom formatting inside the template through properties.
Example:
<div>
<h1>{{ vehicle.status }}</h1>
<div *ngFor="let vehicle of vehicles.dallases">
<div>ID: {{vehicle.vehicle_id}}</div>
<div>Settings: {{vehicle.dallassettings}}</div>
<div>Updated: {{vehicle.dallasupdated}}</div>
<div *ngFor="let d of vehicle.dallas_list">
<div>number: {{d.number}}</div>
<div>auth: {{d.auth}}</div>
</div>
</div>
</div>

how to impliment Search particular record from .json file using angular2

What I need to do is when i enters text inside textbox , i need to filter result inside li
I need do same as here
but this is done using ajax and i need to do using angular2 with data loading from .json file
my index.html is
<div id="search-container">
<div class="search" id="search-btn"></div>
<input #searchBox id="search" type="text" name="search-input" (keyup)="search(searchBox.value)">
<ul class="data-ctrl">
<li ng-repeat="i in items >i[0].name</li>
</ul>
</div>
My app.component.ts is
constructor(public http: Http,public _dmcService: DmcService) {
this._dmcService.getData('prc').subscribe(
data => { this.listingval= "prc"; this.assignJson(data); }
);
}
assignJson function from app.component.ts:
here i assigned data to heroes which is loaded from json file
assignJson(data: any) {
displayContent= data.teacher[0].libraryItems;
for (var i = 0; i <displayContent.length; i++) {
this.heroes[i] = [
{ id: i, name: data.teacher[0].libraryItems[i].display_title.slice(30)}
];
}
}
dmc.service.ts:
getData(filename: string) {
return this.http.get('assets/data/' + filename + '.json').map((res: Response) => res.json());
}
prc.json:
{
"isbn": "9781328694829",
"teacher": [
{
"component": "Core Resources",
"libraryItems": [
{
"id": "9781328694829-00001",
"display_title": "Practice- Ungroup from the Left or from the Right"
},
{
"id": "9781328694829-00002",
"display_title": "Reteach- Ungroup from the Left or from the Right",
}
]
}
}
search function in app.component.ts:
search(term: string): void {
this.searchTerms.next(term);
}
ngOnInit(): void {
let heroes: Observable<Hero[]>;
this.heroes = this.searchTerms
.debounceTime(300) // wait for 300ms pause in events
.distinctUntilChanged() // ignore if next search term is same as previous
.switchMap(term => term // switch to new observable each time
// return the http search observable
? this.heroSearchService.search(term)
// or the observable of empty heroes if no search term
: Observable.of<Hero[]>([]))
.catch(error => {
// TODO: real error handling
console.log(error);
return Observable.of<Hero[]>([]);
});
}
my heroesSearchService is as
#Injectable()
export class HeroSearchService {
constructor(private http: Http) {}
search(term: string): Observable<Hero[]> {
console.log('term:: ',term);
var str = this.http.get(`app/heroes/?name=${term}`)
.map((r: Response) => r.json().data as Hero[]);
return str;
}
}
export class Hero {
id: number;
name: string;
}
my current code not working, can anyone please help me with this.

fail reading object type of json

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