How do I display that JSON in Angular2 - json

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>

Related

While implementing ngrx Observable is showing Object of unknown type

This is my component's typescript code:
import { Component, Input, OnInit } from '#angular/core';
import { Store } from '#ngrx/store';
import { Observable } from 'rxjs';
#Component({
selector: 'app-counter-output',
templateUrl: './counter-output.component.html',
styleUrls: ['./counter-output.component.css']
})
export class CounterOutputComponent implements OnInit {
counter!: number;
counter$!: any;
constructor(private store: Store<{ counter: { counter: number } }>) {
}
ngOnInit(): void {
this.store.select('counter').subscribe((data) => {
this.counter = data.counter;
console.log(data);
});
this.counter$ = this.store.select('counter');
console.log(this.counter$);
}
}
This is its HTML template:
<div>This is the counter:{{(counter$|async).counter}}</div>
<div>This is the counter:{{counter}}</div>
There is an error in line no 1 in the HTML file.
When I am subscribing in the typescript file I am able to get the value, but when I am using it as an observable it is showing an error.
Set a type to counter$.
export interface Counter {
counter: number;
}
....
counter$: Observable<Counter>;
Of course, you have to be sure that the selector returns Counter as data.
EDIT: If you insist to use any (which beats the purpose of using Typescript), you can use the $any() type cast function to suppress this error.
<div>This is the counter:{{ ($any(counter$|async)).counter }}</div>
Have you tried to actually define your counter$ property as an Observable?
Why declare it as any if you already know what type of data is?
export interface myInterfaceData {
counter: number;
}
counter$!: Observable<myInterfaceData>;
<ng-container *ngIf="{ myCounter: counter$ | async } as observable">
<div>
This is the counter: {{ observable.myCounter?.counter }}
</div>
</ng-container>

How to display mock data in html in Angular

I have created mock service file and I want to display in my html but not really sure how to make it display properly so I'll be really appreciated If I can get any help or suggestion.
<div class="container2">
<div class="header" style="height: 400px">
<div class="content3">
<div>
<h1 class="kpi-title">90,346</h1>. // I'm trying to remove this hard code html
<p class="kpi-des">Users Right Now</p> // and display it from my mock data file.
</div>
<div>
<h1 class="kpi-title">250++l</h1>
<p class="kpi-des">Saved</p>
</div>
<div>
<h1 class="kpi-title">$34.5 mill</h1>
<p class="kpi-des">New User per Week</p>
</div>
</div>
</div>
</div>
TS
import { ProductService } from '../../data/product-suite.service';
export class MaxisProductSuiteComponent {
productService: ProductService[];
ngOnIT(){
}
product-suite.service.ts
export class ProductService {
productsuite: ProductSuite[] = [
{
id: 1,
title: '90,346',
description: 'Users',
},
{
id: 2,
title: '$34.5 mill',
description: 'Saved',
},
{
id: 3,
title: '250++',
description: 'New User per Week',
},
];
}
Please find the below code for your solutions:
create a json file assets folder with name output.json.
{
"result" : [
{
"id": 1,
"title": "90,346",
"description": "Users at Ford"
},
{
"id": 2,
"title": "$34.5 mill",
"description": "Saved for Ford"
},
{
"id": 3,
"title": "250++",
"description": "New User per Week"
},
{
"id": 4,
"title": "64%",
"description": "Users At Ford"
}
]
}
in service file write below code:
import { observable, Observable } from "rxjs";
import { MaxisProductSuite } from "src/Model/model";
import { HttpClient } from '#angular/common/http';
import { Injectable } from "#angular/core";
#Injectable()
export class MaxisProductService {
constructor(private http: HttpClient){}
getAllMaxisps():Observable<MaxisProductSuite> {
return this.http.get<MaxisProductSuite>("./assets/output.json");
}
}
then component file add below code:
import { DOCUMENT } from '#angular/common';
import { Component, Inject, OnInit } from '#angular/core';
import { MaxisProductSuite } from 'src/Model/model';
import { MaxisProductService } from 'src/service/MaxisProductService';
#Component({
selector: 'app-temp',
templateUrl: './temp.component.html',
styleUrls: ['./temp.component.scss']
})
export class TempComponent implements OnInit {
maxisps: MaxisProductSuite[];
public resultData:MaxisProductSuite=null;
constructor(#Inject(DOCUMENT) private document: Document, private service : MaxisProductService) {}
ngOnInit() {
this.service.getAllMaxisps().subscribe((res:MaxisProductSuite) => {
console.log(res);
this.resultData =res;
});
}
}
then HTMl file add below code:
<div *ngFor="let item of resultData?.result">
<div class="header" style="height: 400px">
<h1>{{item.id}}</h1>
<h2>{{item.title}}</h2>
<h3>{{item.description}}</h3>
</div>
add below model in model file
export interface MaxisProductSuite {
result : Result[]
}
export interface Result{
id?: number;
title: string;
description: string;
}
I hope it will help you to get the solution.
happy to HELP!
make your service in module provider or make it injectable "root".
inject the service in your component you want to display data in constructor as a dependency injection.
assign your component variable array with productService.
in your HTML loop about your data array using *ngFor=" let product of products".
use you product value in the interpolation {{ product.id }}.

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

Angular2 - cannot display json objects

my boss decided to implement Angular2 into our project. I'm preety new to this technology. I'm trying to display JSON from url, but the result is not as I expected. *ngFor doesn't display any data.
This is the code:
vehicle.service.ts
import { Injectable } from '#angular/core';
import { Http } from '#angular/http';
import 'rxjs/add/operator/map';
#Injectable()
export class VehicleService {
constructor(private http: Http){ }
getVehicle() {
return this.http.get('https://jsonplaceholder.typicode.com/posts')
.map(res => res.json());
}}
vehicle.component.ts
import { Component } from '#angular/core';
import { VehicleService } from './vehicle.service';
#Component({
moduleId: module.id,
selector: 'vehicle-json',
templateUrl: 'vehicle.html',
providers: [ VehicleService ]
})
export class VehicleComponent {
vehicle: Vehicle[];
constructor(private vehicleService: VehicleService){
this.vehicleService.getVehicle().subscribe(vehicle => {
/*console.log(vehicle);*/this.vehicle = vehicle;
});
}
}
interface Vehicle {
id: number;
title: string;
body: string;
}
vehicle.html
<div *ngFor="let vehicle of vehicles">
<h3>{{vehicle.title}}</h3>
<p>{{vehicle.body}}</p>
</div>
test 1-2-3
The output is: "test 1-2-3". I checked if the jsons will be displayed inside the console using: console.log(vehicle); - it worked, it returns Array of Objects.
What am I doing wrong? Any ideas how to fix my code?
You have an error:
this.vehicleService.getVehicle().subscribe(vehicle => {
this.vehicle = vehicle;
})
but in your html you refer to let vechicle of vehicles
You should add an "s" to your this.vehicle to your subscription like so:
this.vehicleService.getVehicle().subscribe(vehicle => {
this.vehicles = vehicle;
})
Edit: Just forgot to meantion to change the local variable vehicle: Vehicle[] to vechicles: Vehicle, but that you figured out that yourself! ;)

Access Typescript Object Variables in Angular2

How do I display the id and title of the below Hero object?
The Hero interface below is mapped according to Firebase JSON response.
hero.component.ts
import {Component, Input} from 'angular2/core';
import {Hero} from '../model/hero';
#Component({
selector: 'hero-component',
template: `
{{hero | json }} this works. This display the Firebase JSON response as seen below
<br>
{{ Object.keys(hero)[0] }} this DOESN'T work
<br>
{{ hero[Object.keys(hero)[0]].title }}this also DOESN'T work
`
})
export class HeroComponent {
#Input()
hero:Hero;
}
hero.ts
export interface Hero {
[id: string]: {
createdAt: number;
isActive: boolean;
title: string;
updatedAt: number;
}
}
Firebase JSON response
{ "-KEMOfA5KFK98AXNhPY0": { "createdAt": 1459607745222, "isActive": true, "title": "Wind Hero", "updatedAt": 1459607745222 } }
update
instead of pipes: [KeysPipe]
use
#NgModule({
declarations: [KeysPipe],
exports: [KeysPipe],
}
export class SharedModule{}
#NgModule({
...
imports: [SharedModule],
})
original
You can't use Object.keys(hero)[0] in the template. No global references can be used, only members of the component.
Instead create a function on your component
getKeys(obj) {
return Object.keys(obj);
}
and then in the template
{{ getKeys(hero)[0] }}
Alternatively you can build a pipe that extracts the keys like for example https://stackoverflow.com/a/34074484/217408
#Pipe({ name: 'keys', pure: false })
export class KeysPipe implements PipeTransform {
transform(value: any, args: any[] = null): any {
return Object.keys(value);
}
}
then use it like
{{ (hero | keys)[0] }}
Don't forget to add the pipe to pipes: [KeysPipe] on the component where you want to use it or alternatively
bootstrap(App, [provide(PLATFORM_PIPES, {useValue: KeysPipe, multi:true})]);
Your code isn't working since Object isn't available in your component.
You could try something like this:
#Component({
selector: 'hero-component',
template: `
{{hero | json }} this works. This display the Firebase JSON response as seen below
<br>
{{ obj.keys(hero)[0] }} this DOESN'T work
<br>
{{ hero[obj.keys(hero)[0]].title }}this also DOESN'T work
`
})
export class HeroComponent {
#Input()
hero:Hero;
obj = Object;
}
or using a method like Günter suggested in his answer.