I am writing a mobile app for Android using Capacitor (v6) and Ionic (v8). I am also using the Vue.JS (v3) framework. Several of the views/pages in my app have some special handling for the hardware “back” button. So I’ve imported the @capacitor/App plugin to add a callback for the back button.
As the view/page is mounted, I call:
this.backListener = await App.addListener('backButton',this.execBack.bind(this))
When the page is unmounted I call:
this.backListener.remove()
Everything works. The callback is invoked as expected when the user taps the hardware back button.
The problem is that there is more than one page/view in my mobile app. For example, first view/page “A” is loaded and displayed. The back-button callback is registered as shown above when view/page “A” is mounted. Then the user taps a component which causes a new view/page “B” to open. This navigation is accomplished by using Vue’s router like this:
this.$router.push("/view-B")
So view/page “B” is now mounted (view/page “A” is still mounted too, but it is not visible). But this new page “B” has it’s own special handling for the “back” button, so page “B” also registers a back-button callback with the code shown above. So now both page “A” and page “B” have callbacks registered. When the user actually taps the hardware “back” button while on page “B”, both callbacks are invoked (one call to the callback registered for page A and another call to the callback registered for page B).
But I don’t want both callbacks to be called. Once page “B” is mounted, it makes no sense for the back-button callback from page “A” to execute any more, even though page “A” is still mounted and waiting to be reactivated when page “B” closes.
Of course, I can unregister the back button callback at any time with the code shown above. But that gets complicated quickly. I have to create a callback so that when page “A” loads page “B”, it unregisters the callback for page “A”. Then when page “B” is closed, page “A” automatically comes to the foreground again. I would need to detect that page “A” is currently being shown an re-register the back-button callback for page “A”. This seems like a nightmare to manage, especially as the pages get nested multiple levels deep. It feels like there should be a simpler way.
When each page has it’s own back-button callback, I want the only the callback for the active page to be invoked. Is there some simple way to implement this, or do I really need register and unregister these callbacks as navigation occurs with the Vue router?