How much can I rely on undocumented return type of router.navigate?

Hello all, I’m hoping that Help Requests is the correct category for this. If not let me know and I’ll move it.

In my app I need to know when the router is done navigating and make a decision based on whether the navigation was completed successfully or cancelled. Right now I’m using the EventAggregator to do this. In my ViewModel I import the Router from aurelia-router and I call router.navigate to navigate to a route. In the same ViewModel, I’m subscribing to the RouterEvent.Complete and RouterEvent.Canceled events to be able to tell when those two things are happening. Here’s a small example (using TypeScript):

import { autoinject } from 'aurelia-framework';
import { EventAggregator, Subscription } from 'aurelia-event-aggregator';
import { Router, RouterEvent, NavigationInstruction, PipelineResult } from 'aurelia-router';

@autoinject
export class MyClass {
    private _router: Router;
    private _ea: EventAggregator;
    private _routerCompletedSubscription: Subscription;
    private _routerCancelledSubscription: Subscription;

    constructor (router: Router, ea: EventAggregator) {
        this._router = router;
        this._ea = ea;
    }
    
    private attached() {
        this._routerCompletedSubscription = this._ea.subscribe(RouterEvent.Complete, (event: { instruction: NavigationInstruction; result: PipelineResult }) => {
            //Some code here to respond to the router navigation completing.
        });
        
        this._routerCancelledSubscription = this._ea.subscribe(RouterEvent.Canceled, (event: { instruction: NavigationInstruction; result: PipelineResult }) => {
            //Some code here to respond to the router navigation being cancelled.
        });
    }
    
    private detached() {
        this._routerCompletedSubscription.dispose();
        this._routerCancelledSubscription.dispose();
    }
    
    private someMethod() {
        const newUrl: string = "http://some.app.url";
        this._router.navigate(newUrl);
    }
}

When I hover over the _router.navigate method I notice that the TypeScript definition says that it returns boolean. I looked at the API docs here and it confirms that. However, when I was playing around with things, I declared a boolean variable to hold the result of the router.navigate method and I put it into console.log to see what the variable was after the navigation. I was suprised to find that what it’s actually returning is Promise<{state: string; value: PipelineResult} (the typing is just my guess, btw, based on what I see in the console. This seems really interesting and I’ve been trying to find the method in the source code to find the actual typings but I’ve been unable to so far.

What I would love to do is to await that router.navigate method and then check out what the value of the PipelineResult is to be able to know what the result was. Something like this:

import { autoinject } from 'aurelia-framework';
//import { EventAggregator, Subscription } from 'aurelia-event-aggregator';
import { Router, /*RouterEvent, NavigationInstruction,*/ PipelineResult } from 'aurelia-router';

@autoinject
export class MyClass {
    private _router: Router;
    private _ea: EventAggregator;
    /*private _routerCompletedSubscription: Subscription;
    private _routerCancelledSubscription: Subscription;*/

    constructor (router: Router/*, ea: EventAggregator*/) {
        this._router = router;
        //this._ea = ea;
    }
    
    private attached() {
        /*this._routerCompletedSubscription = this._ea.subscribe(RouterEvent.Complete, (event: { instruction: NavigationInstruction; result: PipelineResult }) => {
            //Some code here to respond to the router navigation completing.
        });
        
        this._routerCancelledSubscription = this._ea.subscribe(RouterEvent.Canceled, (event: { instruction: NavigationInstruction; result: PipelineResult }) => {
            //Some code here to respond to the router navigation being cancelled.
        });*/
    }
    
    private detached() {
        /*this._routerCompletedSubscription.dispose();
        this._routerCancelledSubscription.dispose();*/
    }
    
    private async someMethod(): Promise<void> {
        const newUrl: string = "http://some.app.url";
        const navResult: Promise<some type here> = this._router.navigate(newUrl);
        await navResult;
        if (navResult.value.status === "completed") {
            //Some code here to respond to the router navigation being completed
        } else if (navResult.value.status === "canceled") {
            //Some code here to respond to the router navigation being cancelled
        }
    }
}

So my two questions are:

  1. Since the docs for router.navigate don’t list the Promise as the return type, is it a bad idea to depend on that as a return type? Is this a function of documentation being incorrect/out of date or an undocumented “feature” that could change?
  2. If it’s not a bad idea to use that Promise, does anybody know what type the router.navigate method is returning or could you point me to the source code for that method so that I could take a look for myself?

P.S. Just a quick update after I tested one other thing… I found that if the URL that I send to router.navigate is the same as the route that I’m currently on the router doesn’t do anything (as expected) and the return value of the router.navigate method is indeed a boolean. However, if any navigation happens it is returning a Promise.