How to display particular rows from JSON data in Ionic 4 - json

I have two JSON data given below:
userMcData:
[
{
"MACHINE_ID":4,
"MCNAME":“RF21”
},
{
"MACHINE_ID":5,
"MCNAME":“RF22”
},
{
"MACHINE_ID":6,
"MCNAME":“RF23”
}
]
userMcData JSON shows the Machine ID and Machine Name.
items:
[
{
"Mcname":“RF21”,
"Side":"L",
"Breaks":101,
“1”:20,
“2”:10,
“3”:15,
“4”:11,
“5”:9,
“6”:10,
“7”:6,
“8”:8,
“9”:12,
“10”:0,
“11”:0,
“12”:0,
“13”:0,
“14”:0
},
{
"Mcname":“RF21”,
"Side":"R",
"Breaks":94,
“1”:18,
“2”:11,
“3”:11,
“4”:3,
“5”:11,
“6”:18,
“7”:10,
“8”:5,
“9”:7,
“10”:0,
“11”:0,
“12”:0,
“13”:0,
“14”:0
},
{
"Mcname":“RF22”,
"Side":"L",
"Breaks":151,
“1”:12,
“2”:13,
“3”:13,
“4”:25,
“5”:15,
“6”:12,
“7”:29,
“8”:17,
“9”:15,
“10”:0,
“11”:0,
“12”:0,
“13”:0,
“14”:0
},
{
"Mcname":“RF22”,
"Side":"R",
"Breaks":316,
“1”:51,
“2”:27,
“3”:23,
“4”:26,
“5”:28,
“6”:57,
“7”:39,
“8”:41,
“9”:24,
“10”:0,
“11”:0,
“12”:0,
“13”:0,
“14”:0
},
{
"Mcname":“RF23”,
"Side":"L",
"Breaks":164,
“1”:15,
“2”:22,
“3”:19,
“4”:14,
“5”:13,
“6”:20,
“7”:15,
“8”:22,
“9”:24,
“10”:0,
“11”:0,
“12”:0,
“13”:0,
“14”:0
},
{
"Mcname":“RF23”,
"Side":"R",
"Breaks":0,
“1”:0,
“2”:0,
“3”:0,
“4”:0,
“5”:0,
“6”:0,
“7”:0,
“8”:0,
“9”:0,
“10”:0,
“11”:0,
“12”:0,
“13”:0,
“14”:0
}
]
items JSON shows the Machine ID,Side,and some more columns. In this JSON, each Machine must have 2 rows.
Both the JSON data are dynamic.
I want to show this data as given below:
I want to show the data as Cards for each Machine from userMcData JSON. In each card, I have to show the particular machine data from the items JSON. I have tried with pipe. And the above image is taken from modified items JSON.
code:
keys.pipe.ts:
import { Pipe, PipeTransform } from '#angular/core';
#Pipe({
name: 'keys'
})
export class KeysPipe implements PipeTransform {
transform(value: any, ...args: any[]): any {
return Object.keys(value);
}
}
HTML Code:
<ion-card *ngFor="let machine of userMcData">
<ion-card-header>
<div>
<span class="alignleft">{{machine.MCNAME}}</span>
</div>
</ion-card-header>
<ion-card-content>
<ion-grid>
<ion-row *ngFor="let item of items">
<ion-col *ngFor="let list of item | keys">
{{item[list]}}
</ion-col>
</ion-row>
</ion-grid>
</ion-card-content>
</ion-card>

I used keyvalue pipe offered by the angular. By default it sorts the result by the key. So had to use a compare function to retain the original order.
So the HTML Code will look like -
<ion-card *ngFor="let machine of userMcData">
<ion-card-header>
<div>
<span class="alignleft">{{machine.MCNAME}}</span>
</div>
</ion-card-header>
<ion-card-content>
<ion-grid>
<ion-row *ngFor="let item of items">
<ng-container *ngIf="item.Mcname === machine.MCNAME">
<ng-container *ngFor="let list of item | keyvalue: originalOrder">
<ng-container *ngIf="!(list.key === 'Mcname' ||
list.key === 'Side' ||
list.key === 'Breaks')">
<ion-col>
{{list.value}}
</ion-col>
</ng-container>
</ng-container>
</ng-container>
</ion-row>
</ion-grid>
</ion-card-content>
</ion-card>
And add the compare function to the TS file -
originalOrder = (a: KeyValue<number, string>, b: KeyValue<number, string>): number => {
return 0;
}
Here is the Output -

You can try this below logic, structuring might change according to how you want to display:
<ion-card *ngFor="let machine of userMcData">
<ion-card-header>
<div>
<span class="alignleft">{{machine.MCNAME}}</span>
</div>
</ion-card-header>
<ion-card-content>
<ion-grid>
<ion-row *ngFor="let item of items">
<ion-col *ngIf="item.Mcname == machine.MCNAME">
<span *ngFor="let item_data in Object.keys(item)" *ngIf="item_data!='Mcname' && item_data!='Side' && item_data!='Breaks'">{{ item[item_data] }}></span>
</ion-col>
</ion-row>
</ion-grid>
</ion-card-content>
</ion-card>

Related

Ionic: button that unchecks all checkboxes

I have a checkbox list setup that will add the selected items into an array which sends it to a service. I have a button that runs a function that empties the array on click, but the checkboxes remain checked.
Here I select items and the red X appears, clicking that will clear the array.
Here is after I click the X, the array clears, but the items remain checked
page.ts
if (this.checkedItems.includes(item)) {
this.checkedItems = this.checkedItems.filter((value) => value != item);
} else {
this.checkedItems.push(item)
}
console.log(this.checkedItems);
}
createRoutine() {
this.workoutService.selectedWorkouts = this.checkedItems;
console.log(this.checkedItems);
}
uncheckAll(){
this.checkedItems = [];
}
page.html
<div>
<ion-searchbar placeholder="Search..." [(ngModel)]="filterTerm" animated="true"></ion-searchbar>
<ion-list class="accordion-list">
<ion-card size="full" >
<ion-card-header>
<ion-item class="workout-title">
<ion-card-title> Workouts</ion-card-title>
<a slot="end"><ion-icon name="close-outline" size="large" color="bic" *ngIf="checkedItems.length > 0" (click)="uncheckAll()"></ion-icon></a>
</ion-item>
</ion-card-header>
<ion-card-content>
<ion-list *ngFor="let workout of bic | filter:filterTerm | orderBy:'asc':'muscle'; let i = index;" class="workout-list" >
<ion-item>
<ion-label>{{workout.name}}</ion-label>
<ion-note>{{workout.muscle}}</ion-note>
<ion-checkbox slot="end" color="bic" (ionChange)="onChange(workout)"></ion-checkbox>
</ion-item>
</ion-list>
</ion-card-content>
</ion-card>
</ion-list>
</div>
So I'm looking for a solution on how to have the uncheckAll() event uncheck the checkboxes after clearing the array.
You need to have an [(ngModel)] for the check box, that will hold the checked status of check box. This should be bounded with the workout node.
We can mark it as [(ngModel)]="workout.isSelected" for example.
Inside uncheckAll loop through the array of bic and set the isSelected of each node as false
Pseudo Codes
Template
<ion-list *ngFor="let workout of bic | filter:filterTerm | orderBy:'asc':'muscle'; let i = index;" class="workout-list">
<ion-item>
<ion-label>{{workout.name}}</ion-label>
<ion-note>{{workout.muscle}}</ion-note>
<ion-checkbox
slot="end"
color="bic"
[(ngModel)]="workout.isSelected"
(ionChange)="onChange(workout)"></ion-checkbox>
</ion-item>
</ion-list>
Component.ts
uncheckAll(){
this.checkedItems = [];
this.bic.forEach(node => node.isSelected = false);
}

How to remove the image element from DOM when 403 error occurs in Angular

Is there a way I can remove the entire image element from DOM when 403 error occurs to that image while fetching it from the API so that the title of the card is expanded to the whole width of the card.
This is what I tried so far
HTML
<div *ngFor="let item of items">
<ion-row>
<ion-col>
<div>{{ item.title }}</div>
</ion-col>
<ion-col size="4" class="ion-text-center">
<img src="{{ item.imageurl }}" (error)="handleImageError($event)" />
</ion-col>
</ion-row>
</div>
TS
handleImageError(e) {
e.target.style.display = 'none';
}
I have created a working example using StackBlitz. Could anyone please help.
You are looking for *ngIf on image container, as it removes / adds the element from the DOM. And you will also have to slightly modify the handleImageError.
StackBlitz
<div *ngFor="let item of items">
<ion-row>
<ion-col>
<div>{{ item.title }}</div>
</ion-col>
<ion-col *ngIf="!item.hide" size="4" class="ion-text-center">
<img [src]="item.imageurl" (error)="handleImageError(item)" />
</ion-col>
</ion-row>
</div>
And then in the script, in the handleImageError - do this:
items = [
{imageUrl: '5353ssa.png'},
{imageUrl: 'https://latam.kaspersky.com/content/es-mx/images/product-icon-KSOS.png'},
{imageUrl: '5353ssa.png'},
{imageUrl: '5353ssa.png'},
]
handleImageError(image) {
image.hide = true;
}
Your problem is about your container. U have two columns. Then u will hide column instead of image. U can use ngIf
https://stackblitz.com/edit/ionic-a5wy8u
<ion-col *ngIf="!car.isSHOW">
<ion-card-content>
<img src="{{car.url}}" (error)="handleImageError(car)">
</ion-card-content>
</ion-col>
in component change its to true
handleImageError(e) {
e.isSHOW = true;
}
I would suggest you to use ngIf to hide the complete image, the way I would have address this is
Create a boolean variable at the top of your component.
let shouldHide = false;
Use this variable and ngIf at your image, you can use this at the container level or the image level itself like.
<img src="{{ imageurl }}" (error)="handleImageError($event)" *ngIf="shoudHide"/>
Assign true in case of error
handleImageError(e) {
e.target.style.display = 'none';
this.shouldHide = true;
}
Hope it helps

How to display a array elements in HTML(ionic 3)

I'm new to ionic. Actually, I'm trying to display products added to cart in cart page. I got value from Foreach method, but when I try to display, it won't show.
cartpage(){
this.cart.cartview().then((result) => {
this.cartdisplay = JSON.parse(JSON.stringify(result));
this.categorydata = JSON.parse(JSON.stringify(this.cartdisplay.data));
console.log('result11:'+JSON.stringify(this.categorydata));
var arr = Object.keys(this.categorydata.items);
//this.cartarray =[];
arr.forEach( a =>{
this.cartarray['orderitem_name']= this.categorydata.items[a].orderitem_name;
this.cartarray['orderitem_quantity']= this.categorydata.items[a].orderitem_quantity;
console.log('cart : '+this.cartarray['orderitem_quantity']);
console.log(a) //item id
console.log(this.categorydata.items[a].cart_id) //product id
})
console.log(this.cartarray);
})
}
in the console log, orderitem_name and orderitem_quantity is displaying, but it does not show in the HTML page.
This is my HTML code:
<ion-card>
<ion-card-header>Items</ion-card-header>
<!--<ion-card-content >Your cart is empty!</ion-card-content>-->
<ion-list no-lines>
<ion-item *ngFor="let tms of cartarray;" >
<ion-avatar item-left>
<img src="">
</ion-avatar>
<h2><b>{{tms.orderitem_name}} x {{tms.orderitem_quantity}}</b></h2>
<div [ngSwitch]="product?.price_discount">
<p *ngSwitchCase="true">₹ <span st></span> <span></span></p>
<p *ngSwitchDefault>₹ <span style="text-decoration: line-through;"></span> <span></span></p>
</div>
<div>
<button primary large>
<ion-icon name="add" (click)="increaseQuantity(i)"></ion-icon>
</button>
<button primary large>
<ion-icon name="remove" (click)="decreaseQuantity(i)"></ion-icon>
</button>
</div>
</ion-item>
</ion-list>
<!--<ion-card-content ><div>Total for this order is ₹ </div></ion-card-content>-->
</ion-card>
Help me to display a value in foreach loop in ionic 3
You can try these
this.cart.cartview().then((result) => {
this.cartarray = Object.keys(result["data"]["items"]).map((key) => {
return result["data"]["items"][key];
});
})
And your html file
<div *ngFor="let tms of cartarray;">
<h2><b>{{tms.orderitem_name}} x {{tms.orderitem_quantity}}</b></h2>
</div>
i don't no ionic so thats why i'am testing with div but it's work fine.
you miss the "tms" variable name before display list of data
<ion-item *ngFor="let tms of cartarray;" >
<h2><b>{{tms.orderitem_name}} x {{tms.orderitem_quantity}}</b></h2>
</ion-item>
You should debug your array like
<ion-item *ngFor="let tms of cartarray;" >
<h2><b>{{tms | json }} x {{tms | json}}</b></h2>
</ion-item>
Thanks

Angular 5 *ngFor array of objects

I have data like this:
Initial data:
var input = [
{ru: "R201", area: "211", unit: "211"},
{ru: "R201", area: "212", unit: "NONE"},
{ru: "R201", area: "HCC", unit: "NONE"}];
Result data:
var result = [
{area: ["211", "212", "HCC"],
ru: "R201",
unit: ["211", "NONE"]}];
I want to looping these data into template using ngFor, after some researches I'm getting stuck at this problem, cannot find a differ supporting object 'R201' of type 'string'. NgFor only supports binding to Iterables such as Arrays.
Here is my function:
this.groupBy = _
.chain(input)
.groupBy('ru')
.map(function(value, key) {
return {
ru: key,
area: _.uniq(_.pluck(value, 'area')),
unit: _.uniq(_.pluck(value, 'unit'))
}
})
.value();
And here is my template:
<ion-list no-lines class="menus">
<ion-item ion-item *ngFor="let p of groupBy; let i=index" (click)="toggleLevel1('idx'+i)" [ngClass]="{active: isLevel1Shown('idx'+1)}">
<ion-row>
<ion-col col-9>
<span ion-text>
<strong>{{ p.ru }}</strong>
<ion-icon [name]="isLevel1Shown('idx'+i) ? 'arrow-dropdown' : 'arrow-dropright'" float-right></ion-icon>
</span>
<ion-list no-lines *ngIf="isLevel1Shown('idx'+i)">
<ion-item no-border *ngFor="let menu of p.ru; let i2=index" text-wrap (click)="toggleLevel2('idx'+i+'idx'+i2)" [ngClass]="{active: isLevel2Shown('idx'+i+'idx'+i2)}"><br>
<span ion-text>
<strong> {{ menu.area }}</strong>
<ion-icon [name]="isLevel2Shown('idx'+i+'idx'+i2) ? 'arrow-dropdown' : 'arrow-dropright'" float-right></ion-icon>
</span>
<ion-list no-lines *ngIf="isLevel2Shown('idx'+i+'idx'+i2)">
<ion-item no-border text-wrap><br>
<span ion-text (click)="openEquipmentPage(p.dataRu,menu.area,menu.unit)">
{{ menu.unit }}
</span>
</ion-item>
</ion-list>
</ion-item>
</ion-list>
</ion-col>
</ion-row>
</ion-item>
</ion-list>
Maybe someone could help me, thank you in advance.
You can manipulate your result according to this.
var grd = .chain(input)
.groupBy('ru')
.map(function(value, key) {
return {
ru: key,
area: _.uniq(_.pluck(value, 'area')),
unit: _.uniq(_.pluck(value, 'unit'))
}
}).value();
this.groupBy = [];
for(let key in grd){
groupby.push({key: key, values:grd[key]});
}

How can I link ion-card to external url dynamically

I've an ion-card that get its contents from a web server, all is working fine except linking ion-card click event to external url, below is my code
<ion-content no-padding >
<ion-item no-padding *ngFor="let item of items" >
<ion-card (click)="goToDetails('{{item.link}}')">
<img class="images" src="http://mydomain/{{item.captionImage}}">
<ion-item text-wrap>
<div class="headings">{{item.title}}</div>
</ion-item>
<ion-card-content text-wrap>
<p>{{item.message}}"</p>
</ion-card-content>
<ion-row>
<ion-col col-9>
<ion-row>
<ion-col>
<img class="owner-logo" src="http://mydomain/{{item.sourceLogo}}">
</ion-col>
<ion-col>
<div class="owner-name">{{item.source}}</div>
</ion-col>
<ion-col></ion-col>
<ion-col></ion-col>
<ion-col></ion-col>
</ion-row>
</ion-col>
<ion-col col-3 text-right>
<button ion-button clear small color="danger" icon-start (click)="regularShare(index)">
<ion-icon name='share'></ion-icon>
Share
</button>
</ion-col>
</ion-row>
</ion-card>
</ion-item>
</ion-content>
my .ts file is
public goToDetails(url : string){
let target = "_self";
this.theInAppBrowser.create(url,target,this.options);
}
I got this error message
Uncaught Error: Template parse errors:
Parser Error: Got interpolation ({{}}) where expression was expected at column 13.
You need to write ion-card like this
<ion-card (click)="goToDetails(item.link)">
If you are in in-build directive like click, ngIf you don't need to use interpolation