Angular 5: Access JSON Object with Template Syntax - json

I get the following JSON represantion from a web service
{
"STAT": {
"Total": 216,
"Average": 2.9722222222222223
},
"PPRP": {
"Total": 31494,
"Average": 19.884390677589384
}
}
Within my component I have the following code:
rawOverview: any
ngOnInit() {
this.service.getPlcOverview().subscribe(
data => {
this.rawOverview = JSON.parse(JSON.stringify(data))
},
err => console.error(err),
() => console.log('done loading foods')
);
}
How can I access PPRP and STAT with template syntax?
I tried the following:
<table class="table table-dark">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Tels with acks</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">PPRP</th>
<td>{{rawOverview.PPRP?.Average}}</td>
</tr>
</tbody>
</table>
but I get an error in the console.
ERROR TypeError: Cannot read property 'PPRP' of undefined
Is it possible to access a JSON object in this way?
Or do I have to create known objects which can access the values?

At the moment, because rawOverview is set asynchronously, it starts life undefined, which is causing your error.
If you move the question mark, it will perform a null safe check, which will prevent the error
<td>{{rawOverview?.PPRP?.Average}}</td>
More on that here

Yes you can and should access it like this.
in the HTML just do something like this:
<tr>
<th scope="row">PPRP</th>
<td>{{rawOverview.PPRP?.Average}}</td>
</tr>
<tr>
<th scope="row">STAT</th>
<td>{{rawOverview.STAT?.Average}}</td>
</tr>

Related

Filling a table with JSON data

I am taking mmy first steps in Angular and was about to try populating a table with data stored in a JSON file. Facing a bit of an odd/unexpected situation there as the table doesn't look exactly how I expected it to look. First things first.
Table code:
<table class="table table-sm table-bordered">
<thead>
<tr>
<th>Transfers</th>
<th>Tools</th>
</tr>
</thead>
<tbody>
<tr *ngFor = "let data of linksArray">
<td>{{ data.Transfers}}</td>
<td>{{ data.Tools}}</td>
</tr>
</tbody>
</table>
What I would like to achieve is that the columns Transfers and Tools get filled with data that uses the corresponding keywords in my JSON file. And here it is
[{"Type":"Transfers","Name":"1","Hyperlink":"#"}, {"Type":"Transfers","Name":"2","Hyperlink":"#"},
{"Type":"Tools","Name":"1","Hyperlink":"#"}, {"Type":"Tools","Name":"2","Hyperlink":"#"}]
The array gets loaded by using this in my .ts file
this.http.get('../../assets/templatefiles/links.json').subscribe(data => {this.linksArray = data as
any [];
console.log(this.linksArray);
},
(err: HttpErrorResponse) => {
console.log (err.message);
}
);
So far all looks good, I see the array popping up in console, but then look at the table and am confused
I would have expected the entries in the 2nd column to start in the first cell. Instead they start in the 3rd? What am I missing here? Been marveling for quite a while now :)
https://stackblitz.com/edit/angular-ivy-hvcyfq
To get this
Transfers Tools
1 10
2 20
You want code roughly like this
<hello name="{{ name }}"></hello>
<table class="table table-sm table-bordered">
<thead>
<tr>
<th>Transfers</th>
<th>Tools</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let data of linksArray">
<td>{{data.Transfers.Name}}</td>
<td>{{data.Tools.Name}}</td>
</tr>
</tbody>
</table>
And, this is the main bit, json roughly like this
linksArray = [
{
Transfers: {
Name:"1",
Hyperlink:"#"
},
Tools: {
Name:"10",
Hyperlink:"#"
}
},
{
Transfers: {
Name:"2",
Hyperlink:"#"
},
Tools: {
Name:"20",
Hyperlink:"#"
}
},
Your existing json looks like this, where the '{' represents one row
[
{
"Type":"Transfers",
"Name":"1",
"Hyperlink":"#"
},
{
"Type":"Transfers",
"Name":"2",
"Hyperlink":"#"
},
{
"Type":"Tools",
"Name":"1",
"Hyperlink":"#"
},
{
"Type":"Tools",
"Name":"2",
"Hyperlink":"#"
}
]

GEt element By id angular 7

hello I need to retrieve the values entered by a form after the post method so I inserted at the service level this code :
list:Client[];
constructor(private http:HttpClient) { }
postClient(formData:Client){
return this.http.post(this.rootURL+'/Clients/',formData);
}
putClient(formData:Client){
return this.http.put(this.rootURL+'/Clients/'+formData.Engagement,formData);
}
getClient(formData:Client){
return this.http.get(this.rootURL+'/Clients/GetClientByName/'+formData.Engagement);
}
and at the component level like this :
getClient(form:NgForm){
this.clientservice.getClient(form.value).subscribe(
res =>{this.client = res as Client}
)
}
and in the HTML code this:
<table class="table table-hover">
<tr>
<th class="tname">Client</th>
<th class="tname">Enagement</th>
<th class="tname">ERP</th>
</tr>
<tr *ngFor="let clt of client">
<td >{{clt.Clientname}}</td>
<td >{{clt.Engagement}}</td>
<td >{{clt.ERP}}</td>
and I can’t get the values by ID with the get I don’t know what is the problem I have neither result or error message
I think your http service(this.rootURL+'/Clients/GetClientByName/) return Client[] not Client.
So, You should cast like this.
this.clientservice.getClient(form.value).subscribe(
res =>{this.client = res as Client[]}
)
But, your response is fixed
{"Engagement":"56789","Clientname":"ClLIENT","ERP":"ERP"}
at component level, no need to edit
getClient(form:NgForm){
this.clientservice.getClient(form.value).subscribe(
res =>{this.client = res as Client}
)
}
you should edit html file.
<table class="table table-hover">
<tr>
<th class="tname">Client</th>
<th class="tname">Enagement</th>
<th class="tname">ERP</th>
</tr>
<tr>
<td >{{client.Clientname}}</td>
<td >{{client.Engagement}}</td>
<td >{{client.ERP}}</td>
</tr>
---------------------------
or need to use ngFor loop, edit component level. and no need to edit component level.
client: Client[] = [];
getClient(form:NgForm){
this.clientservice.getClient(form.value).subscribe(
res =>{
const cli = res as Client;
this.client.length = 0;
Array.prototype.push.apply(this.client, cli)
}
)
}

How to remove scientific notation in nodejs/html and display in decimal only?

I am using a node JS app to send an email using amazon SES using the ses.sendTemplatedEmail API
I have also mentioned the template's pure html file for reference if need be
how do i achieve expected output ? i don't know what is going wrong and why it is using scientific when decimal is specified in JSON
test.js
const aws=require('aws-sdk')
const ses = new aws.SES({ apiVersion: "2020-12-01",region:"us-east-1"});
var a = {
"Items": [
{
"timeSinceInactive": 0.00011574074074074075,
"id": "myid1",
"ssid": "myssid",
"deviceName": "devicename1"
},
{
"timeSinceInactive": 0.00009259259259259259,
"id": "myid2",
"ssid": "myssid2",
"deviceName": "devicename2"
}
]
}
b = JSON.stringify(a)
console.log(b)
async function sesSendEmail(b,ses) {
var params = {
Source: "abc#gmail.com",
Template: "mytemplatename",
Destination: {
ToAddresses: ["xyz#gmail.com"] // Email address/addresses that you want to send your email
},
TemplateData: b,
}
try {
await ses.sendTemplatedEmail(params).promise()
}
catch (err) {
console.log(err)
throw new Error(err)
}
};
function setAwsCredentials() {
awsCredentials = {
region: "us-east-1",
accessKeyId: "",
secretAccessKey: ""
};
aws.config.update(awsCredentials);
console.log("Set credentials successfully")
}
setAwsCredentials()
sesSendEmail(b,ses)
template.html
<table border='2' width='1000'>
<tr>
<th>timeSinceInactive</th>
<th>id</th>
<th>ssid</th>
<th>deviceName</th>
</tr>
<thead>
<tr>
{{#each Items.[0]}}
{{/each}}
</tr>
</thead>
<tbody>
{{#each Items}}
<tr>
{{#each this}}
<td>
{{this}}
</td>
{{/each}}
</tr>
{{/each}}
</tbody>
</table>
Current output:
timeSinceInactive id ssid deviceName
1.1574074074074075E-4 myid1 myssid devicename1
9.259259259259259E-5 myid2 myssid2 devicename2
desired output
timeSinceInactive id ssid deviceName
0.00011574074074074075 myid1 myssid devicename1
0.00009259259259259259 myid2 myssid2 devicename2
EDIT
I need to sort the data as well so converting it to a string is not a feasible alternative unfortunately.
Note
I am using createTemlate API from Amazon SES which supports handlebars.. so the html code is using handlebars by default... that is causing the issue its making it in scientific notation for some reason how do i make it decimal only ?
You might consider converting the numbers to strings before passing them to the template. That way you have control over the formatting.
To my mind you should switch to a template that is less generic and make a call to a custom helper that would display the number as you want. The template will look like this one :
<table border='2' width='1000'>
<tr>
<th>timeSinceInactive</th>
<th>id</th>
<th>ssid</th>
<th>deviceName</th>
</tr>
<thead>
<tr>
{{#each Items.[0]}}
{{/each}}
</tr>
</thead>
<tbody>
{{#each Items}}
<tr>
<td>
{{customFormatNumber timeSinceInactive}}
</td>
<td>
{{id}}
</td>
<td>
{{ssid}}
</td>
<td>
{{deviceName}}
</td>
</tr>
{{/each}}
</tbody>
</table>
And here is the custom helper that you could write (this is just an example, probably not the one you want exactly) :
Handlebars.registerHelper('customFormatNumber ', function(item, options) {
retrun item.toPrecision(10)
});

How to display the value returned by avg function (mysql) in angular

After executing a query, I received the following data which is in Json format which is in myDocData:
data: [
RowDataPacket {
updatedAt: 2020-01-03T18:30:00.000Z,
email: 'charles#hotmail.com',
name: 'charles',
money_spent: 1,
'avg(e.money_spent)': 1
},
RowDataPacket {
updatedAt: 2020-01-11T18:30:00.000Z,
email: 'ank#gmail.com',
name: 'ank',
money_spent: 10,
'avg(e.money_spent)': 6
}
]
angular code:
<table class="content-table" >
<thead>
<tr>
<th>EMAIL</th>
<th>NAME</th>
<th>money spent</th>
<th>UPDATED</th>
<th>AVERAGE</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of myDocData">
<td>{{item.email}}</td>
<td>{{item.name}}</td>
<td>{{item.money_spent}}</td>
<td>{{item.updatedAt}}</td>
<td>{{item.avg(e.money_spent)}}</td>
</tr>
</tbody>
</table>
Issue is that I am unable to display the value given by avg function
(other attributes are displayed correctly).
Change the line:
<td>{{item.avg(e.money_spent)}}</td>
to:
<td>{{item['avg(e.money_spent)']}}</td>
In JS, you can use square bracket notation to get properties of objects.
If you have the control over the back-end code then you can change the query which is returning "avg(e.money_spent)" to "avg(e.money_spent) as avg_money_spent" in this way will not be facing the issue and you can access the value using
<td>{{item.avg_money_spent}}</td>
Or you could also use the previous answer by #Viqas

AngularJs: Convert json string to html table

I am an absolute newbie to angularjs and i have been making my hands dirty from the past 3 days. Now, the requirement is to convert a json string from the rest end point to tabular data. Here is the code i am trying.
$scope.getDataCatalogue = function(){
$http.get('http://api.geosvc.com/rest/US/84606/nearby?apikey=485a35b6b9544134b70af52867292071&d=20&pt=PostalCode&format=json')
.success(function(data, status, headers, config){
//do something with your response
$scope = data;
})
.error(function(error){
console.log("not world");
});
}
$scope.getDataCatalogue = function(){
alert('getDataCatalogue');
}
Now,how can i convert the json to grid from the data. Is this the right way to approach the problem.
If you have a fixed structure coming out of the data then you can simply make use of ng-repeat to iterate through the object(data) and display it on your pre-created table. Fiddle
Example shown below:
Considering this is your object which your assigning to a $scope variable name people. $scope.people = data;
[
{
id: 1,
firstName: "Peter",
lastName: "Jhons"
},
{
id: 2,
firstName: "David",
lastName: "Bowie"
}
]
In your controller:
.success(function(data, status) {
$scope.people = data;
});
In your HTML :
<table>
<tr>
<th>Id</th>
<th>First Name</th>
<th>Last Name</th>
</tr>
<tr ng-repeat="person in people">
<td>{{person.id}}</td>
<td>{{person.firstName}}</td>
<td>{{person.lastName}}</td>
</tr>
</table>
Either do it yourself in the view:
<table>
<thead>
<tr>
<th>header 1</th>
<th>header 2</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in data">
<td>{{row.attribute1}}</td>
<td>{{row.attribute2}}</td>
</tr>
</tbody>
</table>
Or use a library like ui-grid to render a more advanced table.