Issue
I have an array of objects, inside this objects i have some properties that i'm sorting to show on a table when i click on the header.
Since i have more than one column with strings, more than one with number and more than one with date, i wanna know if there is a way to reuse the same code of .sort on the columns with the data type.
something like this:
<table>
<tr>
<th (click)="funcSort('string', 'name')">Name</th>
<th (click)="funcSort('string', 'food')">Favorite Food</th>
<th (click)="funcSort('number', 'age')">Age</th>
<th (click)="funcSort('date', 'birth')">Birth</th>
<th (click)="funcSort('number', 'carbs')">Carbs</th>
<th (click)="funcSort('date', 'training')">Training day</th>
</tr>
<tr *ngFor="let item of list">
<td>{{item.name}}</td>
<td>{{item.food}}</td>
<td>{{item.age}}</td>
<td>{{item.birth}}</td>
<td>{{item.carbs}}</td>
<td>{{item.training}}</td>
</tr>
</table>
typescript:
infos: any = {
name: 'stack',
example: 'example..',
details: [
{nome: "ingrid", idade: 12, destino: "manaus"},
{nome: "ester", idade: 22, destino: "coreia"},
{nome: "sara", idade: 52, destino: "los angeles"},
{nome: "laura", idade: 32, destino: "peru"},
{nome: "priscila", idade: 40, destino: "rio de janeiro"},
{nome: "paula", idade: 39, destino: "londres"},
{nome: "simone", idade: 42, destino: "bahia"},
{nome: "leticia", idade: 26, destino: "argentina"},
{nome: "raissa", idade: 41, destino: "sao paulo"},
{nome: "ana", idade: 15, destino: "suecia"},
]
};
sortDir: boolean = true;
list: any = []
ngOnInit(): void {
let convert = Object.values(this.infos);
this.lista = convert[2]
}
funcSort(type: string, prop: string){
//prop would be the second property so that when I pass the function in HTML, I specify which
//property of the object I want to sort
if(type == 'string'){
if(this.sortDir == false){
this.list.sort(( a: any, b: any ) =>
b.prop.localeCompare(a.prop))
this.sortDir = true
}else if(this.sortDir == true){
this.list.sort(( a: any, b: any ) =>
a.prop.localeCompare(b.prop))
this.sortDir = false
}
console.log('string type!')
}
else if(type == 'number'){
if(this.sortDir == false){
this.list.sort(( a: any, b: any ) =>
b.prop- a.prop))
this.sortDir = true
}else if(this.sortDir == true){
this.list.sort(( a: any, b: any ) =>
a.prop- b.prop))
this.sortDir = false
}
console.log('number type!')
}
else if(type == 'date'){
if(this.sortDir == false){
this.list.sort(( a: any, b: any ) =>
new Date(b.prop).valueOf() - new Date(a.prop).valueOf())
this.sortDir = true
}else if(this.sortDir == true){
this.list.sort(( a: any, b: any ) =>
new Date(b.prop).valueOf() - new Date(a.prop).valueOf())
this.sortDir = false
}
console.log('date type!')
}
}
this code doesn't works because "a.prop.localeCompare(b.prop.localeCompare)" don't exist and the console show an error on a.prop and b.prop. So i wanna know if there is a way to use another prop on the sort method, a way to reuse a piece of code to sort the same type columns, maybe changing the localeCompare to the 1, -1 way? i tried but didn't work...
Solution
When you are using a string to access a particular property, we cannot do test.prop
where prop
is the property name as a string instead go for test[prop]
this will access the property dynamically!
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { bootstrapApplication } from '@angular/platform-browser';
import 'zone.js';
@Component({
selector: 'app-root',
standalone: true,
imports: [CommonModule],
template: `
<table>
<tr>
<th (click)="funcSort('string', 'name')">Name</th>
<th (click)="funcSort('string', 'food')">Favorite Food</th>
<th (click)="funcSort('number', 'age')">Age</th>
<th (click)="funcSort('date', 'birth')">Birth</th>
<th (click)="funcSort('number', 'carbs')">Carbs</th>
<th (click)="funcSort('date', 'training')">Training day</th>
</tr>
<tr *ngFor="let item of list">
<td>{{item.name}}</td>
<td>{{item.food}}</td>
<td>{{item.age}}</td>
<td>{{item.birth}}</td>
<td>{{item.carbs}}</td>
<td>{{item.training}}</td>
</tr>
</table>
`,
})
export class App {
infos: any = {
name: 'stack',
example: 'example..',
details: [
{
name: 'ingrid',
age: 12,
birth: this.randomDate(new Date(2020, 0, 1), new Date(), 0, 24),
food: 'carrot',
carbs: 1200,
training: this.randomDate(new Date(2020, 0, 1), new Date(), 0, 24),
},
{
name: 'ester',
age: 22,
birth: this.randomDate(new Date(2020, 0, 1), new Date(), 0, 24),
food: 'apple',
carbs: 3456,
training: this.randomDate(new Date(2020, 0, 1), new Date(), 0, 24),
},
{
name: 'sara',
age: 52,
birth: this.randomDate(new Date(2020, 0, 1), new Date(), 0, 24),
food: 'banana',
carbs: 756896,
training: this.randomDate(new Date(2020, 0, 1), new Date(), 0, 24),
},
{
name: 'laura',
age: 32,
birth: this.randomDate(new Date(2020, 0, 1), new Date(), 0, 24),
food: 'potato',
carbs: 1243,
training: this.randomDate(new Date(2020, 0, 1), new Date(), 0, 24),
},
{
name: 'priscila',
age: 40,
birth: this.randomDate(new Date(2020, 0, 1), new Date(), 0, 24),
food: 'tomato',
carbs: 2546,
training: this.randomDate(new Date(2020, 0, 1), new Date(), 0, 24),
},
{
name: 'paula',
age: 39,
birth: this.randomDate(new Date(2020, 0, 1), new Date(), 0, 24),
food: 'beans',
carbs: 1234,
training: this.randomDate(new Date(2020, 0, 1), new Date(), 0, 24),
},
{
name: 'simone',
age: 42,
birth: this.randomDate(new Date(2020, 0, 1), new Date(), 0, 24),
food: 'radish',
carbs: 345,
training: this.randomDate(new Date(2020, 0, 1), new Date(), 0, 24),
},
{
name: 'leticia',
age: 26,
birth: this.randomDate(new Date(2020, 0, 1), new Date(), 0, 24),
food: 'fried rice',
carbs: 12000,
training: this.randomDate(new Date(2020, 0, 1), new Date(), 0, 24),
},
{
name: 'raissa',
age: 41,
birth: this.randomDate(new Date(2020, 0, 1), new Date(), 0, 24),
food: 'rice',
carbs: 1500,
training: this.randomDate(new Date(2020, 0, 1), new Date(), 0, 24),
},
{
name: 'ana',
age: 15,
birth: this.randomDate(new Date(2020, 0, 1), new Date(), 0, 24),
food: 'chapathi',
carbs: 1300,
training: this.randomDate(new Date(2020, 0, 1), new Date(), 0, 24),
},
],
};
sortDir: boolean = true;
list: any = [];
constructor() {}
ngOnInit(): void {
let convert = Object.values(this.infos);
this.list = convert[2];
}
funcSort(type: string, prop: string) {
//prop would be the second property so that when I pass the function in HTML, I specify which
//property of the object I want to sort
if (type == 'string') {
if (!this.sortDir) {
this.list.sort((a: any, b: any) => b[prop].localeCompare(a[prop]));
this.sortDir = true;
} else {
this.list.sort((a: any, b: any) => a[prop].localeCompare(b[prop]));
this.sortDir = false;
}
console.log('string type!');
} else if (type == 'number') {
if (!this.sortDir) {
this.list.sort((a: any, b: any) => b[prop] - a[prop]);
this.sortDir = true;
} else {
this.list.sort((a: any, b: any) => a[prop] - b[prop]);
this.sortDir = false;
}
console.log('number type!');
} else if (type == 'date') {
if (!this.sortDir) {
this.list.sort(
(a: any, b: any) =>
new Date(b[prop]).valueOf() - new Date(a[prop]).valueOf()
);
this.sortDir = true;
} else {
this.list.sort(
(a: any, b: any) =>
new Date(a[prop]).valueOf() - new Date(b[prop]).valueOf()
);
this.sortDir = false;
}
console.log('date type!');
}
}
randomDate(start: any, end: any, startHour: any, endHour: any) {
var date = new Date(+start + Math.random() * (end - start));
var hour = (startHour + Math.random() * (endHour - startHour)) | 0;
date.setHours(hour);
return date.toISOString().slice(0, 10);
}
}
bootstrapApplication(App);
Answered By - Naren Murali
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.