emberjs / emberjs/ember.js

router.replaceWith calls pushState on the history object with refreshModel QP

Open
#18,416 7 comments 0 reactions 0 assignees View on GitHub
Has Reproduction Query Params Routing
Dominant language
TypeScript
Stars
22.6k
Forks
4.2k
Avg merge
3d 12h
Merged PRs (30d)
15

Description

https://github.com/mehulkar/ember-example-replace-push-state

I think this may have the same root cause as #15801, but it manifests differently.

## Problem

If a queryParam is configured to `refreshModel: true`, calls to `router.replaceWith` end up calling `pushState` on history instead of `replaceState`.

I'm not totally sure how this would manifest as a "bug" in a browser for an end user, but in my case, I have a custom `Location` using a custom `history` object, and calling `pushState` when we really meant to replace causes it to get an extra entry history entry.

## Debugging

It seems that Ember (or underlying `router.js` lib thinks that because of the queryParams refreshModel config, this replaceWith transition is invalid, and it cancels it and generates its own.

Because router.replaceWith is implemented like this:

```
replaceWith() {
this.transitionTo(...arguments).method('replace');
}
```

the `transitionTo()` promise gets replaced, and all the async stuff that causes the URL to update happens on the *new* promise, which does not yet have the `urlMethod` set to `replace`.

One possible solution here is that instead of using `transitionTo()`, a `Transition` object should be constructed with `urlMethod` set as part of the constructor, so that it does the right thing throughout its lifecycle, but that seems like a really big change.

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.