rfcs icon indicating copy to clipboard operation
rfcs copied to clipboard

Spread Operator In Templates

Open migeorge opened this issue 8 years ago • 12 comments

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.

migeorge avatar Dec 01 '16 17:12 migeorge

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}}

workmanw avatar Dec 01 '16 20:12 workmanw

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...

Panman82 avatar Dec 01 '16 20:12 Panman82

@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!

migeorge avatar Dec 01 '16 22:12 migeorge

@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.

migeorge avatar Dec 01 '16 22:12 migeorge

My use case is:

{{yield
  (hash foo=(component "foo") ...this.moreThings)
}}

amk221 avatar Aug 27 '19 15:08 amk221

@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);
});

buschtoens avatar Aug 28 '19 07:08 buschtoens

The reason I created ember-merge-helper is exactly to solve link-to/query-params problem :)

tchak avatar Aug 28 '19 08:08 tchak

My use case would be:

{{#each components as |component|}}
  {{component component.name ...component.params}}
{{/each}}

basz avatar Sep 15 '19 07:09 basz

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.

chriskrycho avatar Sep 16 '19 14:09 chriskrycho

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 🙂

algodave avatar May 09 '21 06:05 algodave

@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?

sly7-7 avatar Apr 21 '22 12:04 sly7-7

This seems like a good idea, but we need an RFC to move it forward. Is there anything I can do to help facilitate?

wagenet avatar Jul 23 '22 02:07 wagenet