简体   繁体   中英

How do I get my sort function to call a comparison function

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)

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM