recuperate fields of a json - json

I have a json like this :
[ {
"id": 1,
"libraryName": "lib1",
"bookName": "book1",
"bookPrice": 250.45,
"unitSold": 305
},
{
"id": 2,
"libraryName": "lib1",
"bookName": "book2",
"bookPrice": 450.45,
"unitSold": 150
},
{
"id": 3,
"libraryName": "lib1",
"bookName": "book3",
"bookPrice": 120.25,
"unitSold": 400
}]
I want to recuperate all the bookNames of this json in a list without creating the method getBookNames (because I want a standard way for any field of the json)
So, in the component.ts I used :
sales:any;
getSale () {
this.service.getSales().subscribe(data=> {this.sales = data,
console.log(this.sales.bookName)
})
}
It gives me undefined object in the console ! How can I solve this without creating a method getBookNames() ?
This is my class :
export interface Sale {
id: number
bookname : string
Libraryname: string
Bookprice : number
Unitsold : number
}
This is my service:
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { Sale } from './Sale';
#Injectable({
providedIn: 'root'
})
export class MyserviceService {
constructor(private http: HttpClient) { }
getSales () {
return this.http.get<Sale>("http://localhost:8081/sales/all")
}
}

The data obtained from the API is an array. So you could use array map() function to obtain a list of all the properties from the elements. Try the following
sales: any;
unitsSold = [];
getSale () {
this.service.getSales().subscribe(data=> {
this.sales = data,
console.log(data.map(item => item.bookName)); // <-- output: ['book1', 'book2', 'book3'];
console.log(data.map(item => item.id)); // <-- output: [1, 2, 3];
this.unitsSold = data.map(item => item.unitSold); // <-- [305, 150, 400]
});
}
I don't see anything lost here to recuperate.

Related

Why would an angular service api not render to data bindings in the html?

I am still new to angular... But, this html renders as a blank page, nothing is shown in the browser. Console.log will log out the data to the console so I know it is visible. This also causes blank rows in a p-table or any other table that you might be using.
What am I doing wrong?
component.html
<div *ngFor="let item of myData">{{ item.id }}</div> <!-- should be: 1 2 3 -->
<div>{{ item[0].id }}</div> <!-- should be: 1 -->
component.ts
#Component({
selector: 'app-testing-table',
templateUrl: './testing-table.component.html',
styleUrls: ['./testing-table.component.css'],
})
export class TestingTableComponent implements OnInit {
myData: Posts[] = [];
constructor(
private postService: PostService,
) {}
ngOnInit(): void {
this.postService.get().subscribe((resp) => {
console.log('got all posts', resp);
this.myData = resp;
});
}
}
service.ts
import { HttpClient } from '#angular/common/http';
import { Injectable } from '#angular/core';
import { Observable } from 'rxjs/internal/Observable';
import { Posts } from '../models/posts';
#Injectable({
providedIn: 'root',
})
export class PostService {
public URL = 'https://something.com/typicode/demo/posts';
constructor(protected http: HttpClient) {}
public get(): Observable<Array<Posts>> {
return this.http.get<Array<Posts>>(`${this.URL}`);
}
}
model.ts
export class Posts {
id: number;
title: string;
}
Response Data from the API get() service.ts
[
{
"ID": 1,
"Title": "Post 1"
},
{
"ID": 2,
"Title": "Post 2"
},
{
"ID": 3,
"Title": "Post 3"
}
]
This took me a few good days of work with some help from a friend to find out angular is very strict with how it maps the JSON to the Model. The response data has to match 1:1 with the case or it wont work. The error is here:
Make the models match the response:
model.ts
export class Posts {
ID: number;
Title: string;
}
OR
Have the api service change what it returns as JSON, and have it return this instead:
Response Data from the API get() service.ts
[
{
"id": 1,
"title": "Post 1"
},
{
"id": 2,
"title": "Post 2"
},
{
"id": 3,
"title": "Post 3"
}
]

Angular 5 Observable mapping to Json array

My backend return this :
{
"FirstResponse": [
{
"MyField1": "AAA",
"MyField2": "AAAAAAA"
},
{
"MyField1": "BBB",
"MyField2": "BBBBBBB"
},
{
"MyField1": "CCC",
"MyField2": "CCCCC"
}
],
"SecondResponse": [
{
"FirstName": "FirstNameA",
"LastName": "LastNameA"
},
{
"FirstName": "FirstNameB",
"LastName": "LastNameB"
}
]
}
I'd like map FirstReponse to a variable and SecondResponse to another variable.
How can I adapt the code below ?
search(): Observable<any> {
let apiURL = `......`;
return this.http.get(apiURL)
.map(res => res.json())
}
Update : Excepted result
In one variable this :
[
{
"MyField1": "AAA",
"MyField2": "AAAAAAA"
},
{
"MyField1": "BBB",
"MyField2": "BBBBBBB"
},
{
"MyField1": "CCC",
"MyField2": "CCCCC"
}
]
In a second :
[
{
"FirstName": "FirstNameA",
"LastName": "LastNameA"
},
{
"FirstName": "FirstNameB",
"LastName": "LastNameB"
}
]
You could create a new file which exports the model class and then assign it to the returning Observable type. Something like:
new model.ts file
class FieldModel {
Field1: string;
Field1: string;
}
export class valuesModel {
MyValues: Array<FieldModel>;
}
on the service.ts
import { valuesModel } from 'model';
search(): Observable<valuesModel> {
let apiURL = `https://jsonplaceholder.typicode.com/users`;
return this.http.get(apiURL)
.map(res => res.json())
}
Please check this approach, use
import { Http, Response} from '#angular/http';
import { Observable } from 'rxjs/Observable';
public search(){
let apiURL = `https://jsonplaceholder.typicode.com/users`;
return this.http.get(apiURL)
.map((res: Response)=> return res.json();)
.catch((error: Response) => {
return Observable.throw('Something went wrong');
});
}
for this search() method you can subscribe from your component.
And if you want to map output into respected modal then please provide format of same.So that i can help
I don't crealry understan what you wanna get because you not provide example result,
however try this - change line:
.map(res => res.json())
to
.map(res => res.json().MyValues )
using this you will get at the top level similar array like in link you provided in comment below you question: https://jsonplaceholder.typicode.com/users
UPDATE (after question update 9.10.2018)
Currently .map(res => res.json()) returns object that has two fields (variables) "FirstResponse" and "SecondResponse". You can have acces to it by for example (I write code from head):
public async loadData()
{
let data = await this.yourService.search().toPromise();
let firstVariable = data.FirstResponse;
let secondVariable = data.SecondResponse;
...
}
So as you describe in your question/comments in loadData() you get result in two variables as you want.
Or alternative answer - if you wanna do this inside search() then you can do that in such way for example:
search(): Observable<any> {
let apiURL = `......`;
return this.http.get(apiURL)
.map( (res) => {
let data = res.json();
return {
firstVariable: data.FirstResponse,
secondVariable: data.SecondResponse,
}
})
}

Retrieve JSON Data In Angular 5

I am retrieving json data via http.get, my problem is that I cannot get a specific values of my key in typescript.
The data I am returning is in the format (json):
[
{
"id": 1,
"name": "Albany",
"manufacture": "Albany Superior Low Gi Sliced Brown Seed Bread 700g",
"price": 15.49,
"category": "Food",
"type": "Breads",
"image": "data:image/jpeg;base64,/9j/4AAQSkZJ..."
},
{
"id": 2,
"name": "Blue Ribbon",
"manufacture": "Blue Ribbon Brown Plus Low Gi Bread 700g",
"price": 13.99,
"category": "Food",
"type": "Breads",
"image": "data:image/jpeg;base64,/9j/4AAQSkZJRg..."
}
]
In Angular, my service is as below:
export class ProductService {
prodType:ProductModel;
productList:object;
prodList: Array<ProductModel> = [];
prodMap: Map<number, ProductModel>;
constructor( private http: HttpClient ) { }
getAllProducts(): Array<ProductModel>{
this.http.get<Array<ProductModel>>('/product/service/send/all/products').subscribe(
data => {
console.log( data );
},
error => {
console.error("HTTP FAILURE ERROR!!!");
}
);
return this.prodList;
}
getProductByType( productSearch:string ){
this.productList = this.prodList.find( x=> x.getType() == productSearch);
console.log( this.productList);
}
}
The ProductModel is as follows:
export class ProductModel {
private id: number;
private name: string;
private manufacture: string;
private price: number;
private category: string;
private type: string;
private image: string;
// get and setters
The million dollar question; let's say I would to search through my data for product types and only wanted to console-log products with type milk from my json data.
How would I do that? I have searched for similar solution, but they were unhelpful.
First assign the HTTP result to your class member and then filter your datas and then console.log the filtered array items.
export class ProductService {
prodType:ProductModel;
productList:object;
prodList: Array<ProductModel> = [];
prodMap: Map<number, ProductModel>;
constructor( private http: HttpClient ) { }
getAllProducts() {
this.http.get<Array<ProductModel>>('/product/service/send/all/products').subscribe(
datas => {
this.prodList = datas;
},
error => {
console.error("HTTP FAILURE ERROR!!!");
}
);
}
getProductByType( productSearch:string ): Array<ProductModel>{
let filteredProducts:Array<ProductModel> = this.prodList.filter(product => product.type == productSearch);
filteredProducts.forEach(product=> console.log(product);
return filteredProducts;
}
}
You can add the map and modify the response coming from the http get call and filter it before assigning it to the list . of if you want to separate the same then you need split the logic into two methods one to get the vanilla list and then filter the data on top of it
getAllProducts(): Array<ProductModel>{
return this.http.get<Array<ProductModel>>('/product/service/send/all/products').map(data => data.filter(value => value.type == 'milk')).subscribe() ;
}

How to map JSON response to Model in Angular 4

I have tried a lot but I am not able to get endpoint response mapped to my model. I am using HttpClient and Angular4.
I got data back from service but it is not mapped correctly to my model class.
I have following JSON which service is Returning:
{
"result": [
{
"id": "1",
"type": "User",
"contactinfo": {
"zipcode": 1111,
"name": "username"
}
}
]
}
I have created a model in typescript which I will like to map to json response:
export interface result {
zipcode: number;
name: string;
}
This is how i call JSON endpoint.
result : string[] = [];
constructor(private http: HttpClient) { }
public getList(): result[] {
this.http.get<result[]>('url...', { headers: this.headers }).subscribe(
data => {
// 1. Data is returned - Working
console.log('data: ' + data);
this.result= data;
// This is the problem. My data is not mapped to my model. If I do following a null is returned
console.log('data mapped: ' + this.result[0].name);
},
(err: HttpErrorResponse) => {
// log error
}
);
return this.result;
}
You need to import the interface in your component,
import { result } from '.result';
Your interface should look like,
interface RootObject {
result: Result[];
}
interface Result {
id: string;
type: string;
contactinfo: Contactinfo;
}
interface Contactinfo {
zipcode: number;
name: string;
}
and change the type of result as,
result : result;
and assign the result as,
this.result = data;
You can use http://www.jsontots.com/ to create the interface based on JSON
your "data" is an Object, with a property "result". result[] has a property called "contactInfo". in contactInfo you have the data you want, so
//you have no model, so NOT get<result[]>
this.http.get('url...', { headers: this.headers }).subscribe(
data => {
this.result= data.result[0].contactInfo;
}

JSON data with angular2-highcharts

I want to create chart based on the JSON data.
I using angular2-highcharts my ChartsMain component looks like:
#Component({
moduleId: module.id,
selector: 'charts',
templateUrl: 'charts.html',
directives: [CHART_DIRECTIVES,]
providers: [DataService]
})
export class ChartsMain {
result: Data[];
constructor(DataService:DataService) {
DataService.getData().subscribe(res => this.result = res);
this.options = {
chart: {
type: "candlestick"
},
title: {
text: "JSON data"
},
xAxis: {
type: "category",
allowDecimals: false,
title: {
text: ""
}
},
yAxis: {
title: {
text: "Number"
}
},
series: [{
name: "Hour",
data: this.result
}]
};
}
options: Object;
And my DataService looks:
#Injectable()
export class DataService {
http: Http;
constructor(http: Http) {
this.http = http;
}
getData(): Observable<Array<Data>> {
return this.http.get('http://JSON-DATA')
.map(this.extractData)
.catch(this.handleError)
}
private extractData(res: Response) {
let body = res.json();
return body || { };
}
private handleError(error: any) {
// In a real world app, we might use a remote logging infrastructure
// We'd also dig deeper into the error to get a better message
let errMsg = (error.message) ? error.message :
error.status ? `${error.status} - ${error.statusText}` : 'Server error';
console.error(errMsg); // log to console instead
return Observable.throw(errMsg);
}
}
My chart
Where is a problem, why is chart empty? How do I fill the chart with JSON data. JSON data must be in any specific format?
A candlestick chart is typically used to present the open, high, low and close price over a period of time..
Sample expected JSON format looks like this-
[
[1250553600000,23.09,23.46,23.06,23.43],
[1250640000000,23.25,23.61,23.21,23.51],
[1250726400000,23.57,23.82,23.52,23.76],
[1250812800000,23.95,24.20,23.83,24.17],
[1251072000000,24.30,24.39,24.04,24.15],
[1251158400000,24.21,24.42,24.16,24.20],
[1251244800000,24.13,24.22,23.82,23.92],
[1251331200000,24.11,24.22,23.55,24.21],
[1251417600000,24.61,24.64,24.08,24.29],
[1251676800000,24.02,24.12,23.79,24.03],
]
Here is sample component with candlestick highchart-
import { Component } from '#angular/core';
import {JSONP_PROVIDERS, Jsonp} from '#angular/http';
import { CHART_DIRECTIVES } from 'angular2-highcharts';
#Component({
selector: 'high-chart',
directives: [CHART_DIRECTIVES],
providers: [JSONP_PROVIDERS],
template: `
<h2> This is HighChart CandleStick component </h2>
<chart type="StockChart" [options]="options3"></chart>
`
})
export class HighChartsComponent {
options3: Object;
constructor(jsonp : Jsonp) {
jsonp.request('https://www.highcharts.com/samples/data/jsonp.php?a=e&filename=aapl-ohlc.json&callback=JSONP_CALLBACK').subscribe(res => {
this.options3 = {
title : { text : 'CandleSticks' },
rangeSelector : {
selected : 1
},
series : [{
type : 'candlestick',
name : 'CandleSticks',
data : res.json(),
dataGrouping : {
units : [
[
'week', // unit name
[1] // allowed multiples
], [
'month',
[1, 2, 3, 4, 6]
]
]
},
tooltip: {
valueDecimals: 2
}
}]
};
});
}
EDIT:
In your case you are not setting chart options inside subscribe. You should set like this-
this._http.get('http://knowstack.com/webtech/charts_demo/data.json')
.map(this.extractData)
.subscribe((response) => {
this.options = {
title : { text : 'knowstack' },
series : [{
name : 'knowstack',
data : response.json()
}]
};
},
(error) => {
this.errorMessage = <any>error
});
Please note - data from knowstack will only work with simple charts (not candlestick)
EDIT 2: column chart
Please refer below configuration. This is how you can use column chart.
this.options1 = {
title : { text : 'simple column chart' },
series: [{
type : 'column',
data: [["Maths",15],["Physics",16],["Biology",18],["Chemistry",19]]
}]
};
EDIT 3: sample of key-value pair json
import { Component } from '#angular/core';
import { CHART_DIRECTIVES } from 'angular2-highcharts';
#Component({
selector: 'my-app',
directives: [CHART_DIRECTIVES],
styles: [`
chart {
display: block;
}
`]
template: `<chart [options]="options"></chart>`
})
class AppComponent {
constructor() {
var data = [{"key":"Math","value":98},{"key":"Physics","value":78},{"key":"Biology","value":70},{"key":"Chemistry","value":90},{"key":"Literature","value":79}];
this.options = {
title : { text : 'simple chart' },
xAxis: {
type: 'category'
},
series: [{
data: data.map(function (point) {
return [point.key, point.value];
})
}]
};
}
options: Object;
}
Ok it is work. I use service which in my first post, I just changed component: constructor(http: Http, jsonp : Jsonp, DataService:DataService) {
DataService.getData().subscribe(res => this.result = res);
http.request('').subscribe(res => {
this.options = {
chart: {
type: 'column'
},
plotOptions: {
column: {
zones: [{
value: 12,
},{
color: 'red'
}]
}
},
series: [{
data: this.result
}]
};
});
}
options: Object;
in this case json data: [{"key":"Math","value":98},{"key":"Physics","value":78},{"key":"Biology","value":70},{"key":"Chemistry","value":90},{"key":"Literature","value":79}]
How can I split this data like there http://www.knowstack.com/webtech/charts_demo/highchartsdemo4.html