Display JSON Object to front end using services in Angular2 - json

I have been trying to display a json file having multiple arrays in it on the front-end div tag in using Services Angular2 using Typescript. Can anyone help?
Also, If anyone can help transforming this code by adding Model and Interface class would be very helpful.
Here is the code:
SERVICE
export class HttpServiceDemo{
_data: any;
private url: string = "assets/sample.json"
constructor(private http: Http){}
getMyOrder(){
//return this.http.get(this.url)
// .map((response: Response)=> response.json());
return this.http.get(this.url)
.map(res => this.http = res.json().myOrder);
}
}
component.ts
export class SimpleHTTPComponentComponent implements OnInit {
data:any;
Order_date:any;
OrderNumber: number;
P_O_Number:number;
Total: number;
Quote_Status: string;
Expiration_Date: any;
Quote_Created_On: any;
constructor(public vara: HttpServiceDemo) {
}
ngOnInit() {
//calling myorder from json
this.vara.getMyOrder().subscribe(response => {
this.data=response;
for (var myOrder in this.data)
{
console.log(myOrder, this.data[myOrder]);
this.Order_date=this.data[myOrder].Order_Date;
this.OrderNumber=this.data[myOrder].OrderNumber;
this.P_O_Number=this.data[myOrder].P_O_Number;
this.Total=this.data[myOrder].Total;
this.Quote_Status=this.data[myOrder].Quote_Status;
}
})
}
sample.json
---------------
{
"accOrder":[
{
"Order_Date": "10-sep-1981",
"OrderNumber" : "E12345",
"P_O_Number": "P12345",
"Total": "123",
"Quote_Status": "In Progress"
},
{
"Order_Date": "1-oct-1981",
"OrderNumber" : "E82398",
"P_O_Number": "P87815",
"Total": "265",
"Quote_Status": "In Progress"
},
{
"Order_Date": "21-nov-1981",
"OrderNumber" : "E52367",
"P_O_Number": "P76549",
"Total": "454",
"Quote_Status": "In Progress"
},
{
"Order_Date": "10-dec-1981",
"OrderNumber" : "E42840",
"P_O_Number": "P23632",
"total": "123",
"Quote_Status": "Completed"
}
]
}

You are saying your console.log() shows the JSON just fine ?
Then, your data is correctly fetched into your component's data attribute.
You just have to go through your attribute in your template using *ngFor directive then.
Plunkr : https://plnkr.co/edit/4IdV3OHyNFNi90KXQQHP?p=preview
template: `
<div>
<div *ngFor="let order of data.accOrder" style="border: 1px solid lightgrey; padding: 15px; margin: 5px 0;">
Order_Date : {{ order.Order_Date }} <br>
OrderNumber : {{ order.OrderNumber }} <br>
P_O_Number : {{ order.P_O_Number }} <br>
Total : {{ order.Total }} <br>
Quote_Status : {{ order.Quote_Status }} <br>
</div>
</div>
`
PS : No need for your "for" loop inside ngOnInit() , this is not how you should access the data.
You should check out the ngFor doc to learn more about it.
EDIT :
As I said in my comment below, my previous Plunker was using raw data while you use asynchronous data in your use case (it's coming from an Observable sent from your service).
To make it work then, you have to check if your component already received the data before you try to display it. For that, you need to use the *ngIf directive.
New Plunkr : https://plnkr.co/edit/W5qykrh4blplGxTyp8aC?p=preview
template: `
<div *ngIf="data; else loading">
<div *ngFor="let order of data.accOrder" style="border: 1px solid lightgrey; padding: 15px; margin: 5px 0;">
Order_Date : {{ order.Order_Date }} <br>
OrderNumber : {{ order.OrderNumber }} <br>
P_O_Number : {{ order.P_O_Number }} <br>
Total : {{ order.Total }} <br>
Quote_Status : {{ order.Quote_Status }} <br>
</div>
</div>
<ng-template #loading>Fetching the data from the webservice... Wait 3 seconds !</ng-template>
`,
You have to create a parent div to the one with your *ngFor directive. In this parent div, use the *ngIf="data" directive. Everything inside it will not be displayed until there is some data into the data attribute.
I used here an if/else syntax which appeared with Angular4. But you don't need that. That's just here to display a message while there is no data. It could be a loading spinner for example, to let the user know he has to wait.
If you don't want to use this if/else condition, you can do it without it like that :
template: `
<div *ngIf="data">
<div *ngFor="let order of data.accOrder" style="border: 1px solid lightgrey; padding: 15px; margin: 5px 0;">
Order_Date : {{ order.Order_Date }} <br>
OrderNumber : {{ order.OrderNumber }} <br>
P_O_Number : {{ order.P_O_Number }} <br>
Total : {{ order.Total }} <br>
Quote_Status : {{ order.Quote_Status }} <br>
</div>
</div>
`,
Hope this helped :)

Related

How can I display selectBox items in chips?

I want to display data in chips using selectBox, but I got a problem while displaying these items like this:
My TS:
selectedPointsForts: any[]=[];
listPointsForts: any[]=[];
SelectPointsForts() {
this.PointsFortsService.findAll().then((res) => {
this.listPointsForts= res.map(function(obj: any) {
return {
value: {
id: obj.id,
name: obj.libelle
},
label: obj.libelle
};
});
});
}
My HTML:
<p-multiSelect [options]="listPointsForts" [(ngModel)]=" selectedPointsForts" [selectionLimit]=3 [panelStyle]="{minWidth:'12em'}" [maxSelectedLabels]=2></p-multiSelect>
<p>Selected Cars: </p>
<p-chips [(ngModel)]=" selectedPointsForts" > </p-chips>
Can anyone help me to fix this problem !
You can place pTemplate in <p-chips> element to format the chip items' displayed output.
<p-chips [(ngModel)]="selectedPointsForts">
<ng-template let-item pTemplate="item">
{{ item.id }} - {{ item.name }}
</ng-template>
</p-chips>
Sample Solution on StackBlitz
Output
References
Chips (Custom Content)

How to print key and value of object inside template?

how can I print the key and value of the object inside the template?
The template is 'kendo chart series item tooltip'
My HTML
<kendo-chart-series-item-tooltip>
<ng-template let-value="value" let-category="category" let-series="series" let-dataItem="dataItem">
<div *ngFor="let item of dataItem.subObject| keyvalue">
{{item | json}}<br/>
Key:{{item.key}} and Value:{{item.value}}
<br/><br/>
</div>
</ng-template>
</kendo-chart-series-item-tooltip>
My JSON:
[
{
"id": "1Period",
"subObject": [{"Alex":"10"},{"Mathew":"5"}],
},
{
"id": "2Period",
"subObject": [{"Alex":"2"},{"Mathew":"50"}]
}
]
This code doesn't work and it returns this error:
Uncaught Error: Template parse errors:
The pipe 'keyvalue' could not be found
probably you want to set it like this
{
"id": "1Period",
"subObject": [
{
"key":"Alex",
"value":"10"}
}
and your HTML file like this
<kendo-chart-series-item-tooltip>
<ng-template >
<div *ngFor="let item of dataItem.subObject">
<br/>
Key:{{item.key}} and Value:{{item.value}}
<br/><br/>
</div>
</ng-template>
</kendo-chart-series-item-tooltip>
You can define the following custom pipe:
import { Pipe, PipeTransform } from '#angular/core';
#Pipe({
name: 'forObject'
})
export class ForObjectPipe implements PipeTransform {
transform(value: object): string[] {
if (!value) {
return [];
}
return Object.keys(value);
}
}
And use it like that:
<kendo-chart-series-item-tooltip>
<ng-template let-value="value" let-category="category" let-series="series" let-dataItem="dataItem">
<div *ngFor="let key of dataItem.subObject | forObject">
{{dataItem.subObject[key] | json}}<br/>
Key:{{key}} and Value:{{dataItem.subObject[key]}}
<br/><br/>
</div>
</ng-template>
</kendo-chart-series-item-tooltip>
Check out my boilerplate if you have issues defining the pipe.

Displaying object into HTML in Angular

sorry for the noob question.
I created an http request and retrieved some pokemon data and put it in an object called pokemon, like so:
export class AppComponent implements OnInit{
title = 'Pokedex';
apiURL = 'https://pokeapi.co/api/v2/pokemon/1';
pokemon = {};
constructor(private http: HttpClient){}
ngOnInit(): void{
this.http.get(this.apiURL).subscribe(data =>{
const pokemon = {
name: data['name'],
id: data['id'],
abilities: data['abilities'].map( ability => ability['ability']['name']),
types: data['types'].map( type => type['type']['name']),
image: data['sprites']['front_default']
}
console.log(pokemon);
When I console log the object, it outputs in the console fine.
However, when I try to display it in an html {{ pokemon }} it just returns [object, Object]
How can I get around this?
I have tried the methods suggested below.
{{pokemon.name}}, {{pokemon[name]}} and {{pokemon?.name} display a blank page.
{{ pokemon | json }} returns an empty object, in the form of {}.
Am I perhaps doing something else wrong?
You need to use the json pipe
<pre>{{ pokemon | json }}</pre>
OR
<div> Id: {{ pokemon.id }} </div>
<div> Name: {{ pokemon.name }} </div>
<div> Abilities:
<ul>
<li *ngFor="let ability of pokemon.abilities"> {{ ability }}</li>
</ul>
</div>
<div> Types:
<ul>
<li *ngFor="let type of pokemon.types"> {{ types }}</li>
</ul>
</div>
call property as {{pokemon?.name}}
You can't use object directly. You have to access object properties by either . (Dot) notation or object[property] way.
In your case, if you want to use the property of name then use
{{ pokeman.name }}
or
{{ pokeman[name] }}

Displaying Json array returnd from http get

I want to display content from the firebase I get the data from HTTP get request and I want to display it using ngFor
here is how i get the data
///a service
getMessages(){
return this.http.get('https://bigproject-dd88e.firebaseio.com/data.json')
.map((response:Response)=>{
const data: Message[]=response.json();
return data;
}
).catch(
(error:Response)=>{
return Observable.throw('something went wrong');
}
);
}
and here is my component
export class MessagesComponent implements OnInit {
Message=[];
constructor(private global:GlobalService) {
}
ngOnInit() {
this.GenaerateMessages();
}
GenaerateMessages(){
this.global.getMessages().subscribe(
Message=>this.Message=Message
);
}
}
and here is my HTML
<div *ngFor="let item of Message | keyvalue">
<p>{{item.value|json}}</p>
</div>
I get this on the screen
[ { "email": "loay-gohan#hotmail.com", "message": "loayy", "name": "loay", "phone": "123123123" } ]
[ { "email": "example#example", "message": "hi", "name": "..", "phone": "123123" } ]
how can I reach the inside fields name, message, phone...
it looks like eachitem.value contains one array with one object. If this is a case you can reach it like this:
<div *ngFor="let item of Message | keyvalue">
<div>EMAIL: {{ item.value[0].email }}</div>
<div>MESSAGE: {{ item.value[0].message }}</div>
<div>NAME: {{ item.value[0].name }}</div>
<div>PHONE: {{ item.value[0].phone }}</div>
<pre>{{ item.value | json }}</pre>
</div>
If item.value array has more than one object you might want to loop it wit additional inner ngFor
You do not use value.key. Don't you need it?

Getting 'matches' array data within a 'query' from an API and displaying the information

I am having trouble displaying data from querying an API endpoint. The error message is ERROR TypeError: Cannot read property 'name' of undefined. I understand that I have to jump to display the "matches" array but having a lot of difficulty doing so.
This is what the url returns:
{
"query": "An",
"matches": [
{"name": "Jane Hardman", "id": "248086622848468681706182205280565550732"},
{"name": "Gary Aldan", "id": "246529435182620212343890064029443600078"}
]
}
This is my meeting-handler.service.ts file:
constructor(private _httpClient: HttpClient) {}
getListOfEmployees(query: string = '') {
return this._httpClient.get(
`${this.meetingUrl}/employees?q=${query}`);
}
This is my meeting-form.component.ts file:
export class MeetingFormComponent implements OnInit {
employees;
constructor(private _meetingService: MeetingHandlerService) {
this._meetingService.getListOfEmployees('An').subscribe(
res => this.employees = res
)
}
And finally this is my meeting-form.component.html file:
<div *ngFor="let employee of employees"></div>
<p>{{ employee.name }}</p>
The name is inside this.employees.matches and you have to iterate on the matches field.
Can you try this :
<div *ngFor="let employee of employees?.matches.name"></div>
<p>{{ employee }}</p>
Can you try to edit your get request ?
return this.http.get(`${this.meetingUrl}/employees`, {
params: new HttpParams()
.set('q', query)
})
I checked your stackblitz and I found a typo here :
<div *ngFor="let employee of employees?.matches.name"></div>
<p>{{ employee.name }}</p>
Why are you using {{ employee.name }} ? You iterate on name so you employee is already a name.
Try this :
<div *ngFor="let name of employees?.matches.name"></div>
<p>{{ name }}</p>
<div *ngFor="let employee of employees">
<p>{{ employee.name }}</p>
</div>
Moved the closing tag.