Splitting json data in angular2 - json

I am using angular2 to fetch data from node api. Node api returns data in a format like that
{"height":{"low":4,"high":0,"unsigned":true},"currentBlockHash":{"buffer":{"type":"Buffer","data":[8,4,18,32,197,125,99,165,77,70,46,19,215,237,19,57,219,242,168,130,134,153,184,56,68,211,255,62,122,245,216,154,192,254,179,139,26,32,169,218,156,201,73,252,127,198,103,103,43,100,81,90,113,109,163,137,159,156,140,148,125,28,104,79,145,218,72,145,206,6]},"offset":4,"markedOffset":-1,"limit":36,"littleEndian":true,"noAssert":false},"previousBlockHash":{"buffer":{"type":"Buffer","data":[8,4,18,32,197,125,99,165,77,70,46,19,215,237,19,57,219,242,168,130,134,153,184,56,68,211,255,62,122,245,216,154,192,254,179,139,26,32,169,218,156,201,73,252,127,198,103,103,43,100,81,90,113,109,163,137,159,156,140,148,125,28,104,79,145,218,72,145,206,6]},"offset":38,"markedOffset":-1,"limit":70,"littleEndian":true,"noAssert":false}}
I only want to display value of low in angular2 frontend but problem is I am unable to split that json data into key-value pairs. Either angular2 is displaying whole data or nothing.
This is my component code which receives data in json format
import {Component,OnInit} from '#angular/core';
import { AppService } from '~/./../app/app.service';
#Component({
selector: 'dashboard',
styleUrls: ['./dashboard.scss'],
templateUrl: './dashboard.html'
})
export class Dashboard implements OnInit {
constructor(private AppService: AppService) {
}
ngOnInit(){
this.getStats();
}
BlockchainHeight:any;
getStats(){
this.AppService.getblockchaininfo().subscribe(data=>{
console.log(data);
this.BlockchainHeight=data["_body"];
});
}
}
And this is my html code which display data
<div class="row">
<div class="col-xl-4 col-lg-4 col-md-4 col-sm-4 col-4">
<ba-card>
<h3> Blockchain Height</h3>
{{BlockchainHeight}}
</ba-card>
</div>
Any trick or solution to split that json data into key value pairs?

Im not sure about the specifics regarding Angular2, but this will convert a json string into an object with just plain vanilla javascript
var jsonResponse = "{"height":{"low":4,"high":0,"unsigned":true},"currentBlockHash":{"buffer":{"type":"Buffer","data":[8,4,18,32,197,125,99,165,77,70,46,19,215,237,19,57,219,242,168,130,134,153,184,56,68,211,255,62,122,245,216,154,192,254,179,139,26,32,169,218,156,201,73,252,127,198,103,103,43,100,81,90,113,109,163,137,159,156,140,148,125,28,104,79,145,218,72,145,206,6]},"offset":4,"markedOffset":-1,"limit":36,"littleEndian":true,"noAssert":false},"previousBlockHash":{"buffer":{"type":"Buffer","data":[8,4,18,32,197,125,99,165,77,70,46,19,215,237,19,57,219,242,168,130,134,153,184,56,68,211,255,62,122,245,216,154,192,254,179,139,26,32,169,218,156,201,73,252,127,198,103,103,43,100,81,90,113,109,163,137,159,156,140,148,125,28,104,79,145,218,72,145,206,6]},"offset":38,"markedOffset":-1,"limit":70,"littleEndian":true,"noAssert":false}} ";
var decodedJsonObject = JSON.parse(jsonResponse);
var low = decodedJsonObject.height.low;

Related

how to parse a List of Objects in a json file and display it?

I'm trying to use the import method to parse a json file, this is what my code looks like.
import { Component } from '#angular/core';
import * as data from './cities.json';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'weather-app';
cities: any = (data as any).default;
constructor(){}
ngOnInit(){
console.log(data);
}
}
and this is how i'm trying to display it,
<ul *ngFor="let c of cities">
<li>{{c.CityName}}</li>
</ul>
My console log displays everything but it does not appear in the angular app list, What am i doing wrong here? I'll post the json file i'm trying to parse below. thanks in advance :)
{"List":
[{"CityCode":"1248991","CityName":"Colombo","Temp":"33.0","Status":"Clouds"},
{"CityCode":"1850147","CityName":"Tokyo","Temp":"8.6","Status":"Clear"},
{"CityCode":"2644210","CityName":"Liverpool","Temp":"16.5","Status":"Rain"},
{"CityCode":"2988507","CityName":"Paris","Temp":"22.4","Status":"Clear"},
{"CityCode":"2147714","CityName":"Sydney","Temp":"27.3","Status":"Rain"},
{"CityCode":"4930956","CityName":"Boston","Temp":"4.2","Status":"Mist"},
{"CityCode":"1796236","CityName":"Shanghai","Temp":"10.1","Status":"Clouds"},
{"CityCode":"3143244","CityName":"Oslo","Temp":"-3.9","Status":"Clear"}]}
This is because your root object is not of type Array, your object is
{
List: city[]
}
You may access the property List
<ul *ngFor="let c of cities.List">
<li>{{c.CityName}}</li>
</ul>
Note: that your code needs refactoring as it does not appear as clean code. my answer is just to show to you where is the mistake

How to display pdf in frontend Angular from fetched binary data ( Binary data is one the element of received an object from REST API)?

In MongoDB 'certificate' collection have '_id, studentID, file' fields. Simply I can input for each document where data type for '_id' and 'studentID' are the string, and file data type is Binary (this binary auto-generated by MongoDB during insertion for each user pdf file).
From fetched data, I can display into angular (e.g StudentID, SchoolName) but only I can't display pdf from fetched binary data into angular
In node server: (app.js) // given the core code to avoid too long reading
// This for inserting data into MongoDB
**var fs = require('fs');
var pdfBinary = fs.readFileSync("./TestingPurpose.pdf");
var pdf = new mongodb.Binary(pdfBinary);**
db.collection('Test').insert({
dateTime: new Date(dateTime),
studentName: studentName,
Principal: principalName,
file: pdf }
After successfully data importing in MongoDB can see data in MongoDB as below:
{
"_id" : "C1135",
"dateTime" : ISODate("2019-01-23T11:45:52.254+01:00"),
"studentID" : "stu123",
"schoolName" : "XXX Primary School",
"file" : BinData(0,"JVBERi0xLjcNCiW1tbW1DQoxIDAgb2Jq... more 101410 bytes - application/pdf")
}
certificate.model.ts: file
export class Certificate {
_id: string;
dateTime: string;
studentID: string;
schoolName: string;
file: any;
}
Then in Frontend Angular use (user.service.ts) to receive all infro from Node (app.js)::
import { Certificate } from '../model/certificate.model';
cert: Certificate[];
// receiving all students info
getCertificates() {
return this.http.get('http://localhost:5600/aziz/displayAllCertificates');
}
// to get always get an instant update I use refreshGetCertificates()
refreshGetCertificates() {
this.chkSubscrip = this.getCertificates().subscribe((res) => {
this.cert= res as Certificate[];
});
}
In Certificate Component:
(certificate.component.ts):
export class CertificatesComponent implements OnInit, OnDestroy {
myPDF: any;
constructor(
public userService: UserService,
private dialog: MatDialog,
) { }
ngOnInit() {
this.userService.refreshGetCertificates();
}
pdfView(receiveObj) {
this.forPDF = !this.forPDF;
const myUint8 = new Uint8Array(receiveObj);
this.myPDF= myUint8;
}
}
(certificate.component.html):
<div class="rows">
<ul class="settings_test headerclass text-center">
<li style="float: left">ID</li>
<li>Student-ID</li>
<li>School</li>
<li>PDF View</li>
</ul>
</div>
<div *ngFor="let eachCerts of userService.cert">
<div class="row">
<div class="settings_test">
<li style="width:10%">{{eachCerts._id}}</li>
<li style="width:10%">{{eachCerts.studentID}}</li>
<li style="width:10%">{{eachCerts.schoolName}}</li>
<li style="width:10%"> <button (click) ="pdfView(eachCerts.file)"> View as PDF </button></li>
<object *ngIf=forPDF data="{{myPDF}}" ></object>
</div>
</div>
</div>
In each row will show ID, StudentID, SChool-Name and a button('View as PDF'), when the button will be clicked then a popup or a new window will appear to display the pdf file from the fetched pdf binary data.
As posted in the comments, you can use this answer that should solve your issue, with this modification:
At the beginning, you have to convert your data into a blob. In your case that would be:
public getPDFFromFile(file /* place here the correct type of your class*/): Blob {
return new Blob([file.buffer])
}
then you should be able to use the above mentioned answer. As note by MongoDB documentation, you can access the internal binary data via the buffer property which is of type Buffer.

Angular 6 define JSON format of Date

I want to make a POST request to an API. The API expects a date in the following format yyyy-MM-dd HH:mm:ss.SSS.
I have a request object with an attribute of Type Date.
When I make the POST request via
this.http.post<ResponseObject>(url, objectWithDateAttribute, headers);
My API throws an error because the JSON format of the attribute of type date doesn't match.
How can I change the JSON format of the Date attribute when I make the POST request?
The API requires an ISO String you can obtain by calling toISOString() method on your date object.
Your format is yyyy-MM-dd HH:mm:ss.SSS.
let dateAttrib = new Date().toISOString().split('T').join(' ');
You can do it using angular DatePipe. You can convert the date object objectWithDateAttribute by looking at this sample example. Note the providers array and it should also be injected inside the constructor.
import { Component } from '#angular/core';
import { DatePipe } from '#angular/common';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ],
providers : [DatePipe]
})
export class AppComponent {
someDate = new Date();
constructor(private dp : DatePipe) {
console.log(this.dp.transform(this.someDate, 'yyyy-MM-dd HH:mm:ss.SSS'))
}
}

Angular 2 - Using/displaying JSON data fetched through HTTP, or mocked

I'm working on an Angular 2 application, and I'm trying to use JSON data, either local/mocked or fetched via HTTP, and display it on a component. I have an injectable service that will do the fetching/mocking -
import { Injectable } from 'angular2/core';
#Injectable()
export class TestService {
testString:string = "";
testDetails: string = "";
constructor() { }
getTestDetails(): Promise<string> {
this.testDetails = {
"status": "success",
"message": "Data save successful",
"data": {
"Random_Data_1": "Random Data 1",
"Random_Data_2": "Random Data 2"
}
};
return Promise.resolve(JSON.stringify(this.propertyDetails));
}
}
And then I have a component that uses the service via Dependency Injection -
import { Component, OnInit } from 'angular2/core';
import {TestService} from "./test.service";
#Component({
selector: 'test',
templateUrl: './test.component.html',
styleUrls: []
})
export class TestComponent implements OnInit {
testDetails: string = "";
constructor(private testService: TestService) { }
ngOnInit() {
this.display();
}
display(): void {
this.testService.getTestDetails()
.then(
testDetails => {
this.testDetails = JSON.parse(testDetails);
},
errorMessage => {
console.error("Something failed trying to get test details");
console.error(errorMessage);
}
);
}
}
The component HTML -
<div class="content">
<p> Test Details </p>
<p> {{ testDetails.data.Random_Data_1 }} </p>
</div>
The problem is, the HTML is erroring out trying to display the items in the testDetails JSON. I initially used it with md-tabs, so the first try would error out, but the other tabs would read the data fine. Also, the ngOnInit would be called twice when the error occurs. I have narrowed it down to the data coming in and the object types that is causing me the headache.
I know I can create a Details class and declare testDetails of type Details, and then map the JSON data into the class, but the thing is, I want to work with generic data, and only know a few components that will be present in the data. Is there a way to read the JSON, and use the data without having to define a separate class for each scenario ?
I have a plunker with the most basic stuff set up. The actual setup runs fine on my local system up until where I try to access the JSON data in the HTML, at which point the browser throws a cryptic error. The skeleton code doesn't even run on Plunker. That said, the structure in the Plunker defines the structure of my app and the data flow. Plunker with the basic setup
What is the best way to achieve this ? What is the standard/best practice to do this ?
Throwing another option out there, since you asked about best way to achieve this. Might not be the best idea, this is subjective ;) But if I were you...
Thinking about the future, where you will use real backend, it could be nice to use mock json file. If/when you move over to a real backend, you wouldn't basically need to change anything else but the url of the requests :)
So I set up a simple example for you. Here I used Observables, but you can use Promises if you prefer that. Here's more info on HTTP if you want/need to read up on that. Most important thing is that you have the HttpModule imported in your app module.
You have your file with JSON and in your service make http-requests to that:
getTestDetails() {
return this.http.get('src/data.json')
.map(res => res.json())
}
Your display-method:
display() {
this.testService.getTestDetails()
.subscribe(data => {
this.testDetails = data;
});
}
And in the template use the safe navigation operator to safeguard null/undefined values:
<div class="content">
<p> Test Details </p>
<p> {{ testDetails?.data?.Random_Data_1 }} </p>
</div>
Here's a
Demo
As said, this is to give another approach on how to implement the things you want to achieve, and this would probably be my preferred way :)
Use
<p *ngIF="testDetails.data.Random_Data_1 "> {{ testDetails.data.Random_Data_1 }} </p>
This is because there is no data initially.Hope this helps you.

Saving dates in Angular 2 and JSON

This has been a very difficult problem I have run into with my Angular 2 app. I am trying to format my API (MongoDB) so that each new "post" added by the admin can be fetched by the DATE (not time) by the front end. For example, my schema looks like this:
{name: "The best product ever",date: "25092016",quantity: 345},{name:"The okayest product ever",date: "26092016",quantity: 544,}
As you can tell, the date property is a single number. I then have a function that fetches the data from the object with the current date. However, this is the problem. The date format I am using for the JSON is 'ddMMyyyy'. This worked well for the date pipe in the HTML template, but I cannot seem to be able to format any date in a variable to match this format, or a similar format. All the dates in Angular 2 classes show GMT and timestamps, etc.
How to I format a date in Angular 2 components to match a short succinct string format?
You can use that DatePipe even in your code. :)
https://plnkr.co/edit/6pbHMVSTmndvs9CqYYUL?p=preview
import {Component, NgModule} from '#angular/core'
import {BrowserModule} from '#angular/platform-browser'
import {DatePipe} from '#angular/common';
#Component({
selector: 'my-app',
template: `
<div>
<h2>Hello {{name}}</h2>
</div>
`,
})
export class App {
name:string;
constructor() {
this.name = 'Angular2'
let dp = new DatePipe('de-DE' /* locale .. */);
this.name = dp.transform(new Date(), 'ddMMyyyy');
console.log(name);
}
}
#NgModule({
imports: [ BrowserModule ],
declarations: [ App ],
bootstrap: [ App ]
})
export class AppModule {}
Or you want to use a library like Moment.js..