Mapping between two different Angular models - json

I'm trying to map Order.ts to OrderAction.ts, but getting the error Cannot ready property '0' of undefined. This error is coming up when I try to map the Order properties to OrderAction properties.
Here is Order.ts:
export class Order {
OrderId: number;
FunctionStatusList?: OrderFunctionStatus[];
}
export class OrderFunctionStatus {
FunctionTypeCode: number;
AvailableActions: OrderAvailableAction[];
}
export class OrderAvailableAction {
ActionLabel: string;
ActionValue: string;
}
Here is OrderAction.ts:
export class OrderAction {
FunctionTypeCode: number;
SelectedAction: string;
OrderList: AvailableAction[];
}
export class AvailableAction {
OrderId: number;
IsAvailableAction: boolean;
AvailableActions?: OrderAvailableAction[];
}
Here is the code that I wrote:
orders: any[] = [];
orderActionList: any[] = [];
ngOnInit() {
this.orders = this.orderService.getCheckedOrders();
this.orders.forEach((order: Order, i) => {
let orderAction: OrderAction = new OrderAction();
orderAction.OrderList[i].OrderId = order.OrderId;
orderAction.FunctionTypeCode = order.FunctionStatusList[i].FunctionTypeCode;
orderAction.AvailableActions = order.FunctionStatusList[i].AvailableActions;
orderAction.IsAvailableAction = order.FunctionStatusList[i].AvailableActions.length > 0 == true || false;
this.orderActionList.push(orderAction);
});
}
Here is a sample of the Order.ts json:
{
"OrderId": "1",
"FunctionStatusList": [{
"FunctionTypeCode": "1",
"AvailableActions": [{
"ActionLabel": "1",
"ActionValue": "1"
}]
}]
}
Here is a sample of the OrderAction.ts json:
{
"FunctionTypeCode": "1",
"SelectedAction: "1",
"OrderList": [{
"OrderId": "1",
"IsAvailableActionsLoaded": "1",
"AvailableActions": [{
"ActionLabel": "1",
"ActionValue": "1"
}]
}]
}

I'm not sure where exactly you're getting the error, but I did the following and it converts Order to OrderAction: https://plnkr.co/edit/VEHAdk3qPRIFkEAU?preview
The meat of the code is this:
this.orders.forEach((order: Order, i) => {
this.orderActions.push({
FunctionTypeCode: order.FunctionStatusList[i].FunctionTypeCode,
SelectedAction: null,
OrderList: [
{
OrderId: order.OrderId,
IsAvailableActionsLoaded:
order.FunctionStatusList[i].AvailableActions.length > 0,
AvailableActions: order.FunctionStatusList[i].AvailableActions,
},
],
});
});
I left SelectedAction as null because it was unclear how this value would be set.

Related

Angular 13 - How to get pager details from the JSON response

I work on Angular 13 and I face an issue in that I can't retrieve pager data from the JSON.
The items array returned success but I can't return pager details.
So how to do it?
{
"items": [
{
"id": 3,
"itemNameER": "قلم",
"itemNameEN": "pen",
"description": "1"
},
{
"id": 4,
"itemNameER": "قلم",
"itemNameEN": "pencil",
"description": null
},
{
"id": 5,
"itemNameER": "قلم",
"itemNameEN": "pen2",
"description": null
},
{
"id": 8,
"itemNameER": "car",
"itemNameEN": "car",
"description": "1"
},
{
"id": 9,
"itemNameER": "mobile",
"itemNameEN": "mobile",
"description": "1"
}
],
"pager": {
"numberOfPages": 2,
"currentPage": 1,
"totalRecords": 6
}
}
What I had try is:
items?:ItemsData[];
export interface ItemsData {
id:number;
itemNameER:string;
itemNameEN:string;
description:string;
}
retrieveAllItems(pageNumber: number = 0): void {
this.erpservice.getAll(pageNumber)
.subscribe(
data => {
this.items=data.items;
console.log(data);
},
error => {
console.log(error);
});
}
How to extract pager data from JSON for the numberOfPages, currentPage and totalRecords?
Updated post
This is the information for the getAll return type.
So how to get pager data details?
export interface DataWrapper {
items: ItemsData[];
}
getAll(pageNumber: number): Observable<DataWrapper> {
let params = new HttpParams();
if (pageNumber)
params = params.append('pageNumber', pageNumber);
let httpOptions = {
params: params
};
return this.http.get<DataWrapper>(baseUrl,httpOptions);
}
What I had try is:
pager: any;
this.pager = data.pager;
But I get an error:
Property 'pager' does not exist on type 'DataWrapper'.ts(2339)
<ul>
<li *ngFor="let item of items | paginate: { currentPage:pager.currentPage }; let i = index">
{{ pager.numberOfPages * (pager.currentPage - 1) + i }}
</li>
</ul>
The error message is quite clear. The DataWrapper interface doesn't have a pager property.
You need to:
Add the pager property into DataWrapper interface.
Define the IPager interface.
export interface DataWrapper {
items: ItemsData[];
pager: IPager;
}
export interface IPager {
numberOfPages: number;
currentPage: number;
totalRecords: number;
}

Map JSON for Chartjs with Angular 7

Im trying to map JSON Data to show it in a Bar-Chart. The final Array I need has to look like this:[883, 5925, 17119, 27114, 2758].
Actually, the Array I want to use to set the barChartData (dringlichkeitenValues[])seems to be empty. Sorry for my bad coding skills. Can anyone show me how to solve this Problem?
JSON:
[{
"id": 1,
"value": 883
},
{
"id": 2,
"value": 5925
},
{
"id": 3,
"value": 17119
},
{
"id": 4,
"value": 27144
},
{
"id": 5,
"value": 2758
}]
api.service.ts
getDringlichkeiten(): Observable<IDringlichkeit[]> {
return this.http.get<IDringlichkeit[]>(this.ROOT_URL + '/aufenthalte/dringlichkeit');}
dringlichkeit.ts
export interface IDringlichkeit {
id: number;
value: number;
}
bar-chart.component.ts
export class BarChartComponent implements OnInit {
public dringlichkeitValues:number[] = [];
public dringlichkeiten: IDringlichkeit[];
public barChartLabels:String[] = ["1", "2", "3", "4", "5"];
public barChartData:number[] = this.dringlichkeitValues;
public barChartType:string = 'bar';
constructor(private aufenthaltService: AufenthaltService) {
}
ngOnInit() {
this.loadData();
this.getDringlichkeitValues();
}
loadData(){
this.aufenthaltService.getDringlichkeiten()
.subscribe( data => this.dringlichkeiten = data);
}
getDringlichkeitValues(){
let dringlichkeitValues:number[]=[];
this.dringlichkeiten.forEach(dringlichkeit=>{
dringlichkeitValues.push(dringlichkeit.value)
this.dringlichkeitValues = dringlichkeitValues;
});
return this.dringlichkeitValues;
}
}
UPDATE:
I updated my component but now my Array is still empty after subscribing to the Observable.
bar-chart.component.ts
chart: Chart;
dringlichkeiten: IDringlichkeit[] = [];
constructor(private aufenthaltService: AufenthaltService) {
}
ngOnInit() {
this.aufenthaltService.getDringlichkeiten()
.subscribe( data => {
this.dringlichkeiten = data;
//dringlichkeiten-Array full
console.log(this.dringlichkeiten);
});
//dringlichkeiten-Array empty
console.log(this.dringlichkeiten);
this.chart = new Chart('canvas', {
type: 'bar',
data: {
labels: this.dringlichkeiten.map(x => x.id),
datasets: [
{
label: 'Dringlichkeiten',
data: this.dringlichkeiten.map(x => x.value),
backgroundColor: ['#FF6384', '#4BC0C0', '#FFCE56', '#E7E9ED', '#36A2EB']
}
]
},
});
}
To get the "values" from your JSON array, you can use:
dringlichkeiten.map(x => x.value)
This will get you an array you require, i.e.:
[883, 5925, 17119, 27114, 2758]
You can then pass this array to chartJS for it to render you a chart like so:
this.chart = new Chart('canvas', {
type: 'bar',
data: {
labels: dringlichkeiten.map(x => x.id),
datasets: [
{
label: 'My Bar Chart',
data: dringlichkeiten.map(x => x.value),
backgroundColor: ['red', 'green', 'yellow', 'blue', 'orange']
}
]
},
});
Take a look at this simplified working SlackBlitz example.
Hope this helps!

Angular 4+ handling multiarray json response best practice

user.ts
import { Company } from "./company";
export class User{
token: string;
companies: Company;
name: string;
email: string;
currentCompanyID: string;
constructor(){
}
}
company.ts
export class Company{
companyId: string;
name: string;
orgNo: string;
constructor(){
}
}
service.ts
getData(): Observable<User> {
return this.http.get(this.url).map((res: Response) => res.json())
}
component.ts
//call to my api in service.ts
this.avrs.getData().subscribe(
res => {
console.log("Result");
console.log("main res: " + res);
console.log("Name: " + res.name);
console.log("companyid: " + res.currentCompanyID);
console.log("companies: " + res.companies);
console.log("token: " + res.token);
console.log("user data: " + res.companies.companyId);
console.log("user data: " + res.companies.name);
console.log("user data: " + res.companies.orgNo);
},
error => {
console.log(error);
},
() => {
}
);
}
Output
Result
main res: [object Object]
Name: undefined
companyid: 28764
companies: [object Object]
token: lkjdfjsgosdfjuguerujgoiehjiughdskjge9r8w
user data: undefined
user data: undefined
user data: undefined
Json Response example:
{
"user": {
"id": 123456,
"company_id": "28764",
"name": "TEST",
"email": "test#dummy.com",
"mobile": "91273493412412",
"locale": "en",
"companies": [
{
"companyId": "idww",
"name": "nameww",
"orgNo": "orgww",
"roles": [
{
"role": "Admin"
},
{
"role": "Guest"
}
],
"services": []
},
{
"companyId": "idqq",
"name": "nameqq",
"orgNo": "orgqq",
"roles": [
{
"role": "Admin"
},
{
"role": "Guest"
}
],
"services": []
},
],
},
"token": "lkjdfjsgosdfjuguerujgoiehjiughdskjge9r8w",
"currentCompanyID": "28764"
}
I want to get:
token,
companyid,
user -> name,
user -> companies array
The question is basically what is the best way (best practice) to handle many array in a json file in Angular 2+? As you can see with my output I'm only getting companyid and token data, and not getting companies array or user data.
Create Role Model:
export class Role{
id: number;
name: string;
constructor(attrs: any = null) {
if (attrs) {
this.build(attrs);
}
}
build(attrs: any): void {
this.id = attrs.id;
this.name = attrs.name;
}
}
Create Company Model:
export class Company{
id: number;
name: string;
roles: Array<Role>;
services: any;
constructor(attrs: any = null) {
if (attrs) {
this.build(attrs);
}
}
build(attrs: any): void {
this.id = attrs.id;
this.name = attrs.name;
this.services = attrs.services;
if(attrs.roles) {
this.roles = attrs.roles.map(
r => new Role(r)
);
}
}
}
Create User Model:
export class User{
id: number;
name: string;
email: string;
companies: Array<Company>;
constructor(attrs: any = null) {
if (attrs) {
this.build(attrs);
}
}
build(attrs: any): void {
this.id = attrs.id;
this.name = attrs.name;
this.email = attrs.email;
if(attrs.companies) {
this.companies = attrs.companies.map(
c => new Company(c)
);
}
}
}
By doing so, you create entities automatically. According to your Json Response example, you need to create another model. Let's call it Data!
export class Data{
user: User;
token: string;
currentCompanyID: string;
constructor(attrs: any = null) {
if (attrs) {
this.build(attrs);
}
}
build(attrs: any): void {
this.currentCompanyID = attrs.currentCompanyID;
this.token = attrs.token;
this.user = attrs.user;
}
}
Retrieve data from sample service method like this:
getData(): Observable<any>{
return this.http
.get('awesome_url')
.map((data: any) => new Data(data));
}
Hope I help!

Iterate through ArrayList for specific key-value in Angular 5

How do I iterate through my arrayList and return keys of of specific values? My data is in a Json format as follows:
[
{
"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/4AAQSkZJRgA..."
},
{
"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/4AAQSkZJRgABA..."
},
{...},
{...},
...
]
I was able to return the following data:
I have written the following codes to fetch a single product for type-Milk:
#Component({
selector: 'app-milk-cream',
templateUrl: './milk-cream.component.html',
styleUrls: ['./milk-cream.component.css']
})
export class MilkCreamComponent implements OnInit {
allProducts: Array<Product> = [];
quantity: number = 1;
resultArray:any;
constructor( private prod: ProductService) { }
CallbackFunctionToFindTypeById(prod) {
return prod.type === 'Milk';
}
ngOnInit() {
this.allProducts = JSON.parse(localStorage.getItem('product-data') );
//console.log( JSON.stringify( this.allProducts ) );
var productMilk = this.allProducts.find(this.CallbackFunctionToFindTypeById);
console.log( productMilk );
}
}
interface Product {
id: number;
name: string;
manufacture: string;
price: number;
category: string;
type: string;
image: string;
}
I then edited CallbackFunctionToFindTypeById method, for it to loop and return an arrayList with products of Milk type; the problem is I could not call that method in ngOnInit (not sure that it works too):
CallbackFunctionToFindTypeById(prod) {
for (var i=0; i < this.allProducts.length; i++){
if ( prod.type === 'Milk' ){
this.allProducts[i];
}
}
return this.allProducts;
}
I am new in Angular 5 and TypeScript.
You should be using filter which returns all the items in the array that macthes the predicate
var productMilk = this.allProducts.filter(item => item.type === 'Milk');

Set nested JSON Response as rowdata to ag-grid in Angular4

I am new to angular and doing a sample project in which I want to show some JSON data in a grid.
I'm using ag-grid for the same.
I have the following Json response that I'm getting from a rest API :-
[
{
"id": 64,
"name": "Utopia",
"language": "English",
"genres": [
"Drama",
"Science-Fiction",
"Thriller"
],
"status": "Ended",
"image": {
"medium": "http://static.tvmaze.com/uploads/images/medium_portrait/0/474.jpg",
"original": "http://static.tvmaze.com/uploads/images/original_untouched/0/474.jpg"
}
},
{
"id": 65,
"name": "Bones",
"language": "English",
"genres": [
"Drama",
"Crime",
"Medical"
],
"status": "Ended",
"image": {
"medium": "http://static.tvmaze.com/uploads/images/medium_portrait/80/201202.jpg",
"original": "http://static.tvmaze.com/uploads/images/original_untouched/80/201202.jpg"
}
}
]
I was able to successfully bind the data for the simple keys like id, name, language etc. but when it comes to binding the nested object I'm not able to do it.
If you look at the above json response, The 'image' field is an object. How can I get the value of 'medium' or 'original' key from it and just show the image in my row ?
Some help is appreciated, as this is the point I'm getting stuck at.
Below is my component code :-
shows.component.ts
#Component({
selector: 'app-shows',
templateUrl: './shows.component.html',
styleUrls: ['./shows.component.css']
})
export class ShowsComponent implements OnInit {
public gridOptions: GridOptions;
public tvShowsColumnDefs = new ShowColumn;
public showMetaData: any;
constructor(private _contentService: ContentService, private _router: Router,
private _route: ActivatedRoute) {
// GridOptions Initialized
this.gridOptions = <GridOptions>{};
this.gridOptions.columnDefs = this.tvShowsColumnDefs.columnDefs;
}
ngOnInit() {
// Prepare Grid Row Data
this.prepareRowData();
}
prepareRowData() {
// API Call for getting TV-Shows
this._contentService.getAllShows()
.subscribe(response => {
const shows = response;
console.log('TVShows-API Response ', shows);
// Setting Grid RowData using api response
this.gridOptions.api.setRowData(shows);
});
}
show.columnDef.ts
export class ShowColumn {
public columnDefs = [
{ field: 'id', headerName: '', width: 50 },
{ field: 'image', headerName: '', width: 50, cellRendererFramework: null},
{ field: 'name', headerName: '', width: 250},
{ field: 'language', headerName: 'Language', width: 100},
{ field: 'genres', headerName: 'Genres', width: 250},
{ field: 'status', headerName: 'Status', width: 145 }
];
constructor() { }
}
The nested properties are accessible by the dot notation (.), e.g.:
{ field: 'image.medium', headerName: '', width: 50}
For the nested arrays, a value-getter will most likely do the job:
function genreValueGetter(params) {
const arr = params.data.genres as Array<string>;
return arr.join(', ');
}
{ headerName: 'Genres', valueGetter: genreValueGetter, width: 250},
First let me build classes:
export class myShow {
image: myImage;
id: number;
...
constructor(obj: any) {
this.document = new myImage(obj.image);
this.id = obj.id;
...
}
}
export class myImage {
medium: string;
original: string;
constructor(obj?: any) {
if(obj){
this.medium = obj.medium;
this.original = obj.original;
}
}
}
Then you can use .map operator
allShows: myShow[] = [];
prepareRowData(){
this._contentService.getAllShows().map((shows: myShow[])=> {
return shows.map((show: myShow)=>{
return new myShow(show);
})
}).subscribe((allShows)=> {
this.allShows = allShows;
});
}