Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUGFIX] Using query params helper outside of link-to #18458

Merged
merged 4 commits into from
Oct 8, 2019

Conversation

Alonski
Copy link
Member

@Alonski Alonski commented Oct 3, 2019

The (query-params) helper has always been able to be used outside of link-to.
This PR broke it: #17779

Fixes: #18076

Recommendations:
This should be backported to the version in which #17779 was included.

Thanks a lot to @rwjblue for the help in fixing this 😄

Using (query-params) helper outside of a link-to is incorrectly failing
Using (query-params) helper outside of link-to should not throw
!(lastModel && lastModel.isQueryParams)
);
let { _models: models } = this;
if (models.length > 0) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need to keep this.query === UNDEFINED (and maybe assert you can’t have both)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@chancancode Can you please help me understand exactly what you mean? What should the code be?

Copy link
Member

@chancancode chancancode Oct 3, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (this.query === UNDEFINED) {
  let { _models: models } = this;

  if (models.length > 0) {
    let maybeQueryParams = models[models.length - 1];

    if (isQueryParams(maybeQueryParams)) {
      this.query = maybeQueryParams.values;
      models.pop();
    }
  }
} else {
  assert(
    'Cannot pass a QueryParams object in @models and @query at the same time',
    this.models.length === 0 || isQueryParams(this.models[this.models.length - 1])
  );
}
// packages/@ember/-internals/routing/lib/system/query_params.ts

import { Option } from '@glimmer/interfaces';

export default class QueryParams {
  constructor(readonly values: Option< object> = null) {
  }

  get isQueryParams(): true {
    return true;
  }
}

export function isQueryParams(obj: unknown): obj is QueryParams {
  return typeof obj === 'object' && obj !== null && obj['isQueryParams'] === true;
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually don't know why the QueryParams constructor accepts null here, is that a public API?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@chancancode - In general, I agree that you shouldn't be able to set both @query and pass a (query-param as the last model, however I don't think we can check this.query === UNDEFINED unless we also change where we save off the query param value. Given the snippet you suggested above, we would only update this.query the first time (not for each subsequent didReceiveAttrs where we could have a completely new value).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@chancancode I don't understand the query_params.ts snippet.
This will change the behavior of the class. Why is values not a property anymore?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay sorry I think I understand the problem now. I know how to fix it but I'll do it later. You can revert to what you had before here (removing the this.query === UNDEFINED check and the assertion I added).

Copy link
Member

@chancancode chancancode Oct 4, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Alonski in TypeScript, constructor(readonly values: Option<object> = null) is a shorthand for declaring the field and assigning it from the constructor:

export default class QueryParams {
  constructor(readonly values: Option<object> = null) {
  }

  get isQueryParams(): true {
    return true;
  }
}

...is the same as...

export default class QueryParams {
  readonly values: Option<object>;

  constructor(values: Option<object> = null) {
    this.values = values;
  }

  get isQueryParams(): true {
    return true;
  }
}

@Alonski
Copy link
Member Author

Alonski commented Oct 4, 2019

@chancancode I push some more code. Is this what you wanted?
I had to negate the assertion to get tests passing

@Alonski
Copy link
Member Author

Alonski commented Oct 4, 2019

CI Failure seems like a false negative


if (typeof lastModel === 'object' && lastModel !== null && lastModel.isQueryParams) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (typeof lastModel === 'object' && lastModel !== null && lastModel.isQueryParams) {
if (isQueryParams(lastModel)) {

@Alonski
Copy link
Member Author

Alonski commented Oct 5, 2019

@chancancode Reverted commit

@NullVoxPopuli
Copy link
Sponsor Contributor

This is exciting! Once this is merged & back ported, I can start upgrading a bunch of things to 3.12 from 3.8 :)

@chancancode chancancode merged commit f786e42 into emberjs:master Oct 8, 2019
@chancancode
Copy link
Member

Oops, I should have used squash and merge. Oh well.

chancancode added a commit that referenced this pull request Oct 8, 2019
[BUGFIX] Using query params helper outside of link-to

(cherry picked from commit f786e42)
chancancode added a commit that referenced this pull request Oct 8, 2019
[BUGFIX] Using query params helper outside of link-to

(cherry picked from commit f786e42)
@chancancode
Copy link
Member

Backported to beta and release, I think we usually hold off on LTS backports until the stable release has been cut.

@Alonski
Copy link
Member Author

Alonski commented Oct 8, 2019

Thanks! So this will be backported after 3.14 or 3.15 is released?

@Alonski Alonski deleted the bugfix/query-params-helper branch November 7, 2019 05:53
@Alonski
Copy link
Member Author

Alonski commented Nov 12, 2019

@chancancode Any idea when this will be backported to 3.12?

rwjblue added a commit that referenced this pull request Nov 17, 2019
Backport/bugfix query params helpers pr #18458 issue #18076
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Regression] [v3.10] The (query-params) helper can only be used when invoking the {{link-to}} component.
4 participants