kruschid / typesafe-routes

Spices up your favorite routing library by adding type safety to plain string-based route definitions.
https://kruschid.github.io/typesafe-routes/
MIT License
102 stars 8 forks source link

Angular - Need for '/' for absolute routes in routeLink #34

Closed Indeedornot closed 2 weeks ago

Indeedornot commented 1 year ago

Hi! First of all thank you for helping with keeping my project typesafe.

Issue

However I've run into an issue recently When routing from typescript this works just fine, because the relativity isn't based on the slash sign but rather on the { relative: true} option

    async onSubmit() {
                //...
        void this.router.navigateByUrl(AppRoutes.artists.show({ id: id }).$);
    }

However when routing from html using [routeLink] prop on a tag it causes routing to be relative due to lack of /

<li class="action">
    <a [routerLink]="AppRoutes.artists.show({ id: lastOccasion.id }).$">Continue</a>
</li>

Workaround

A possible workaround is to do something like this

<li class="action">
    <a [routerLink]="'/' + AppRoutes.artists.show({ id: lastOccasion.id }).$">Continue</a>
</li>

However that does not seem as too good of a thing to have to do

There is also a possibility to define routes like so:

    static artists = {
        show: route('artists/:id', { id: intParser }, {}),
        new: route('artists/new/:id', { id: intParser }, {}),
        update: route('artists/update/:id', { id: intParser }, {})
    };

However Angular routing system does not support registering routes that start with / Returns an error

main.ts:7 Error: NG04014: Invalid configuration of route '/artists/:id': path cannot start with a slash
    at validateNode (router.mjs:2782:19)
    at validateConfig (router.mjs:2718:9)
    at Router.resetConfig (router.mjs:5086:60)
    at new Router (router.mjs:4970:14)
    at Object.Router_Factory [as factory] (router.mjs:5428:23)
    at R3Injector.hydrate (core.mjs:9290:35)
    at R3Injector.get (core.mjs:9178:33)
    at router.mjs:6340:33
    at core.mjs:27458:41
    at Array.forEach (<anonymous>)

Proposed solution

Addition of another property for getting the path alongside the $, for example .absolute or other syntax that basically does the same as $ but adds the slash at the beginning

kruschid commented 3 weeks ago

After attempting to reproduce your use case, I have come to the conclusion that implementing your route hierarchy with the library version you are currently using might be inconvenient.

However, in version 12, you could define an abstract route tree as follows:

const routes = createRoutes({
    artists: {
        path: ["artists"],
        children: {
            show: { path: [int("id")]},
            new: { path: ["new", int("id")]},
            update: { path: ["update", int("id")]},
        }
    },
});

In this example, artists is the parent route of show, new, and update.

To render an absolute path, use:

routes.artists.new.$render({ path: {id: 123} }); // => /artists/new/123 

And for a relative path, use:

routes._.artists.new.$render({ path: {id: 321}}); // => artists/new/123 

In this instance, the _ link operator indicates the first segment of the relative path artists.

Regarding the process of registering routes for Angular, I have already proposed a solution in a different answer: https://github.com/kruschid/typesafe-routes/issues/35#issuecomment-2291037853.

First of all thank you for helping with keeping my project typesafe.

Thank you for contributing. ;-)