Sometimes a route can resolve with multiple records like so:
model() {
const profile = ...;
const user = ...;
return RSVP.hash({
profile,
user,
});
},
So then you'd think you could use link-to like so:
{{link-to 'My Profile' 'profiles.show' (hash user=user profile=profile)}}
This doesn't work because the hash helper returns EmptyObject and extractQueryParams tries to call .hasOwnProperty() on it, resulting in an error.
There's a workaround to this which involves using an action with transitionTo but it feels like a poor experience.
This is an issue I've had with Ember for years. What's the correct way to pass multiple records to link-to if not this?
I'm using ember-cli 3.0.2.
Edit: I've started using the following helper in place of hash as a workaround:
import { helper } from '@ember/component/helper';
export function plainObject(params, hash) {
const object = {};
// NOTE: `hash` is an `EmptyObject` so we convert to a POJO so that it can be
// used with `link-to`.
Object.keys(hash).forEach(k => object[k] = hash[k]);
return object;
}
export default helper(plainObject);
This doesn't work because the hash helper returns EmptyObject and extractQueryParams tries to call .hasOwnProperty() on it, resulting in an error.
This is a bug, we can (and should) totally fix this (swapping to ’queryParams’ in obj instead of obj.hasOwnProperty(‘queryParams')). Would you mind taking a crack at a PR?
Yep, I can take a look tomorrow.
@rwjblue it might be a few days before I can get to this.
I wouldn't mind giving this a go, Hacktoberfest and all that :) That's if you can't @mhluska.
@Parrryy go for it 😄
This doesn't work because the hash helper returns EmptyObject and extractQueryParams tries to call .hasOwnProperty() on it, resulting in an error.
This is a bug, we can (and should) totally fix this (swapping to
’queryParams’ in objinstead ofobj.hasOwnProperty(‘queryParams')). Would you mind taking a crack at a PR?
where is this code?
packages/@ember/-internals/routing/lib/system/route.ts:2207:48: if (!combinedQueryParameterConfiguration.hasOwnProperty(propName)) {
packages/@ember/-internals/routing/lib/utils.ts:16:50: if (possibleQueryParams && possibleQueryParams.hasOwnProperty('queryParams')) {
> packages/@ember/-internals/routing/lib/system/router.ts:1668:22: if (!queryParams.hasOwnProperty(key)) {
@mhluska - I'm actually unable to reproduce the original issue, I wrote a test that _should_ have failed but didn't:
['@test [GH#17018] using `hash` helper for model']() {
this.addTemplate('index', `{{link-to 'Post' 'post' (hash id="bar")}}`);
this.addTemplate('post', 'Post: {{model.id}}');
this.router.map(function() {
this.route('post', { path: '/posts/:post_id' });
});
return this.visit('/')
.then(() => {
this.assertComponentElement(this.firstChild, {
tagName: 'a',
attrs: { href: '/posts/bar' },
content: 'Post',
});
return this.click('a');
})
.then(() => {
this.assertText('Post: bar');
});
}
@rwjblue maybe the issue here is that in (hash user=user profile=profile), user and profile are not ids but models. I'm not sure that this should be supported, since passing a model to link-to is already controversial.
The whole (hash ....) invocation is seen as a "model" from the {{link-to's perspective.
Isn't passing a record to link-to pretty standard? It should prevent the route from reloading data. That's the reason I want to pass two records via hash - to prevent reloading data.
@rwjblue that's strange. The only thing I can think of is maybe different versions than I was using?
Define standard...
It works right now but it's been decided that in general it's not a good pattern and in the future it might be no longer supported.
There was at least one RFC related to this, maybe more:
https://github.com/emberjs/rfcs/pull/283
@mhluska Are you able to create a test replicating the issue?
I am also not able to reproduce the issue and have written a test that replicates the scenario originally reported. The test passes — there are no issues retrieving the record passed to route via link-to hash.
https://github.com/emberjs/ember.js/pull/17769
If everything looks good with the test, I guess we can close this issue?
Yep, thank you @shawnren!