rfcs
                                
                                 rfcs copied to clipboard
                                
                                    rfcs copied to clipboard
                            
                            
                            
                        Spread Operator In Templates
Problem
Currently there is no way to pass dynamic parameters to certain Template Helpers. I'll call out the query-params helper in this case as an example.
Typically we'd use it in the following way:
{{#link-to 'route' (query-params sort="asc" status="complete")}}
Which would give us a link to /route?sort=asc&status=complete
This works well, but there is no way to pass a set of dynamic values to the helper. If we have the following in a component:
params: {
  sort: 'asc',
  status: 'complete'
}
You can't destructure the parameters in the template:
{{#link-to 'route' (query-params params)}}
Solution
We should add support for a spread operator (similar to the one in javascript) for use in templates. I would see something like this looking like:
{{#link-to 'route (query-params ...params)}}
Which would end up being the same as:
{{#link-to 'route' (query-params sort="asc" status="complete")}}
But would allow us to change params and have it reflect in the helper.
I've been hoping we would see a spread or splat operator for a long time. There is actually an open PR in the handlebars repo https://github.com/wycats/handlebars.js/pull/1149. In theory it should be compatible with the query-params helper.
A really huge use case is being able to use the component helper in a much more dynamic way. We lost this ability when Ember.ContainerView was removed and haven't fully got it back. Eg:
{{#each dynamicComponents as |compInfo|}}
  {{component compInfo.class ...compInfo.args}}
{{/each}}
Another solution is to make this work: {{#link-to 'route' (query-params params)}} The (query-params) helper could accept the first positional param as the hash;
export default Ember.Helper.helper(function(params, hash) {
  let queryParams = Ember.assign({}, params[0], hash);
  // ...
});
Of course this only addresses the query params problem and not other uses cases...
@workmanw I'll keep an eye on that PR, we might just have to wait until that lands in handlebars. I agree that it would be great to be able dynamically insert components too!
@Panman8201 For my use case modifying the query-params helper directly would solve my problem and may be a good short term fix, but I think the spread operator would be a much more powerful addition.
My use case is:
{{yield
  (hash foo=(component "foo") ...this.moreThings)
}}
@amk221 You could use @tchak's ember-merge-helper:
{{yield
  (merge this.moreThings foo=(component "foo"))
}}
One issue with above helper (AFAICT) is that it does not track changes on moreThings, as this is the full implementation:
import { helper } from '@ember/component/helper';
import { assign } from '@ember/polyfills';
export default helper(function(hashes, hash) {
  // return assign(Object.create(null), ...hashes, hash);
  return assign({}, ...hashes, hash);
});
The reason I created ember-merge-helper is exactly to solve link-to/query-params problem :)
My use case would be:
{{#each components as |component|}}
  {{component component.name ...component.params}}
{{/each}}
Another plus side for being able to splat arguments and similar is that it makes one variant of higher-order components quite nice: you can just wrap an existing component, make some template-layer tweaks/wrapping and forward all the inbound arguments to it.
I have the same use case as @workmanw @amk221 and @basz and I totally agree with @chriskrycho : a spread operator would be the best friend of the {{component}} helper 🙂
@chriskrycho Sorry to bother you about this old one, but do you know what is the status of this ? I mean, I've searched a bit, but I can't find if today we can splat arguments, passing them to the {{component}} helper?
This seems like a good idea, but we need an RFC to move it forward. Is there anything I can do to help facilitate?