emberjs / emberjs/ember.js

transitionTo() doesn't behave the same as app.visit() on duplicate routes

Open
#18,321 0 comments 1 reaction 0 assignees View on GitHub
Routing
Dominant language
TypeScript
Stars
22.6k
Forks
4.2k
Avg merge
3d 12h
Merged PRs (30d)
15

Description

## Issue

If you define two routes with the same name, but different `path` options, I'm able to boot my app and visit both paths successfully, but `transitionTo` with a URL fails. E.g.:

```js
// app/router.js
this.route('foo', { path: '/foo/:id' });
this.route('foo', { path: '/foo/:title/:id' });
```

## Repro with Ember 3.12

https://github.com/mehulkar/ember-example-dupe-route-name

This diff in particular should be easy to grok without running: https://github.com/mehulkar/ember-example-dupe-route-name/commit/fcf4a724b8d9696a738e3671158e05d35749e57b

## Use Case

There are two parts to this use case:

1. Two path structures for the same application state.

This is to support both `/post/1` and `/post/my-title/1` for SEO and backwards compatibility ("don't break the web", as they say)
2. `transitionTo()` with fully-formed server-vended URLs.

Our server gives us links for our app based on a number of factors (such as geo and locale), so we use those both for `router.transitionTo()` and `` in templates.

## Workaround

Define routes with for both path configurations with different names.

### drawbacks

- Have to add a `Route` handler for each duplicate and either subclass one to the other, or configure the `templateName` and `controllerName` for one to the other.
- To get validation that all features on both forms are working, we have to write acceptance tests for both forms, bloating our test suite.

## Investigation

I looked into a couple things before giving up:

1. Using `applicationInstance.visit()` instead of `transitionTo()`. This almost worked, but would not apply to `LinkTo`, and maintaining a fork/extension of that component seemed like a nightmare. I'm also not sure if using this API would be great in the long run.
2. Digging into the code path for both, but got stuck at:

- `transitionTo` calls [`transitionTo` in router.js](https://github.com/tildeio/router.js/blob/v6.2.5/lib/router/router.ts#L862-L877)
- `visit()` calls [`handleURL` in router.js](https://github.com/tildeio/router.js/blob/v6.2.5/lib/router/router.ts#L840-L857)

Both of these call `doTransition` under the hood but with slightly different arguments, and the former calls `.method()` argument. I stopped digging at that point.
- Also looked at `route-recognizer` and at one point duplicate routes *were* explicitly disallowed, but then that assertion [was commented out](https://github.com/tildeio/route-recognizer/blob/master/lib/route-recognizer.ts#L552).

There is no indication in the guides or anywhere if this use case should be supported or not, but I think a decision should be made one way or the other (with a hard error in `Router.map`, if it's not supported).

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.