aurelia / router

A powerful client-side router.
MIT License
121 stars 115 forks source link

Change return signature of router navigate() and navigateToRoute() from boolean to NavigationResult #650

Closed matthewcorven closed 4 years ago

matthewcorven commented 4 years ago

Fix for #648 to correct typings. Calllers of navigate()/navigateToRoute() could await the routing to complete, but didn't know it due to typings. @davismj

CLAassistant commented 4 years ago

CLA assistant check
All committers have signed the CLA.

matthewcorven commented 4 years ago

@davismj and perhaps type NavigationResult would be more clearly named AwaitableNavigationResult?

davismj commented 4 years ago

@matthewcorven thx for the PR, definitely helps me see what's up.

I think the fix needs to be a bit more robust here. It starts in history / browser where navigate has a boolean return type (https://github.com/aurelia/history/blob/master/src/index.js#L56, https://github.com/aurelia/history-browser/blob/master/src/browser-history.ts#L54), which is only accepted because of other insufficient typings around history options (https://github.com/aurelia/history-browser/blob/master/src/browser-history.ts#L111, https://github.com/aurelia/history-browser/blob/master/src/browser-history.ts#L297, https://github.com/aurelia/history-browser/blob/master/src/browser-history.ts#L54).

Additionally, I don't like the NavigationResult typing. Consuming one requires testing for a Promise first: const result: boolean = await Promise.resolve(this.router.navigate('foo');. This implementation detail should not be the burden of an end developer, who should simply be able to await the method.

I'll go ahead and fix this in all three libraries by:

This will be a breaking change. Currently, the NavigationResult type includes PipelineResult | boolean, which is a difficult type to work with. I will unify them as NavigationResult = { completed: boolean }, and transform all flat boolean returns into a NavigationResult. This means, moving forward, any navigation results, no matter where they come from, can be consumed like this:

const { completed } = await router.navigate('foo');

matthewcorven commented 4 years ago

Thanks @davismj !