Click handling with addEventListener and removeEventListener

I have a function that runs each time my page view enters. It looks for links in (user-generated) content that match a pattern and then adds event listeners to those links so that they’re treated differently than other links, opening them in-app where appropriate. This works just fine as long as the user only clicks any given link once. The problem comes when the user, say, clicks a link on page 1, opening page 2, and then returns to page 1 and clicks the link again. At that point, the page is opened twice (with each repetition, the duplicate page numbers increase exponentially). Below you’ll see that I’ve attempted to prevent this by removing the listener after it fires and also by adding the once option for addEventListener.

I think the issue has something to do with the Typescript conventions that make it a bit more difficult to add and remove dynamically-added event listeners, so this may just be some obscure syntax issue. Or it could be that I’m missing something more obvious. Any ideas?


This should fire each time a page enters (including, I think, when the view enters via the “back” button)

ionViewDidEnter() {
  this.getInAppLinks();
}

Here is a truncated version of that function…

async getInAppLinks() {
  let elems = <NodeList>document.querySelectorAll(".content a");
  if (elems) {
    for (var i = 0; i < elems.length; i++) {
      let elem = <HTMLAnchorElement>elems[i];
      let link = new URL(elem.href);

      // define listener with name so it can be removed
      var inapplistener = e => {
        e.preventDefault();
        elem.removeEventListener("click", inapplistener, <any>{ once: true }); // remove on use
        this.pushStoryPage();
       };
       
       // add listener with *once* option
       elem.addEventListener("click", inapplistener, <any>{ once: true });
    }
  }
}

To get around the issue with managing event listeners, I just added an onClick event to the links that need to open in-app.

// pushStoryPage() is a class method so I need to bind this in order to use it inside a click handler 
this.pushStoryPage = this.pushStoryPage.bind(this);

// add click handler
elem.onclick = e => {
  e.preventDefault();
  this.pushStoryPage(story_id);
};