Issue
Trying to write some clean JS sort functions. Below is a click handler on a button in my template, it calls the individual methods to sort by different properties.
(click)="addresses.sort(sortByTown)"
Which calls the method below. It works great which is nice!
sortByTown(address1: any, address2: any): number {
const a = address1.town.toUpperCase();
const b = address2.town.toUpperCase();
if (a > b) {
return 1;
} else if (a < b) {
return -1;
}
return 0;
}
The problem I’m having, is that I’ve got about 4 of these sort methods, and I’d like to put the if statements into their own function for getting better at writing DRY code. So I’ve tried the below approach, but the compareFunction never even get’s called. What am I doing wrong?
sortByTown(address1: any, address2: any): number {
const a = address1.town.toUpperCase();
const b = address2.town.toUpperCase();
return this.compareAddresses(a, b);
}
compareAddresses(a: string | number, b: string | number): number {
if (a > b) {
return 1;
} else if (a < b) {
return -1;
}
return 0;
}
TypeError: Cannot read property 'compareAddresses' of undefined
at sortByStreetName (address.component.ts:43)
at Array.sort (<anonymous>)
at AddressComponent_Template_button_click_9_listener (address.component.html:10)
at executeListenerWithErrorHandling (core.js:15182)
at wrapListenerIn_markDirtyAndPreventDefault (core.js:15217)
at HTMLButtonElement.<anonymous> (platform-browser.js:582)
at ZoneDelegate.invokeTask (zone-evergreen.js:406)
at Object.onInvokeTask (core.js:28500)
at ZoneDelegate.invokeTask (zone-evergreen.js:405)
at Zone.runTask (zone-evergreen.js:178)
Solution
Most probably using this
inside the callback that’s defined as a plain JS function is running into scoping issues.
Try to define sortByTown()
as an arrow function.
sortByTown = (address1: any, address2: any): number => {
const a = address1.town.toUpperCase();
const b = address2.town.toUpperCase();
return this.compareAddresses(a, b);
}
Update: As pointed out by @yurzui in the comments, defining compareAddresses()
as an plain JS function wouldn’t change the behaviour as it doesn’t depend on member variables.