Skip to content

Spread Operator In Templates #184

Open

Description

@migeorge

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.

Activity

  1. workmanw commented on Dec 1, 2016

    @workmanw

    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 handlebars-lang/handlebars.js#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}}
  2. Panman82 commented on Dec 1, 2016

    @Panman82

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

  3. migeorge commented on Dec 1, 2016

    @migeorge
    Author

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

  4. migeorge commented on Dec 1, 2016

    @migeorge
    Author

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

  5. amk221 commented on Aug 27, 2019

    @amk221

    My use case is:

    {{yield
      (hash foo=(component "foo") ...this.moreThings)
    }}
  6. buschtoens commented on Aug 28, 2019

    @buschtoens
    Contributor

    @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);
    });
  7. tchak commented on Aug 28, 2019

    @tchak
    Member

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

  8. basz commented on Sep 15, 2019

    @basz

    My use case would be:

    {{#each components as |component|}}
      {{component component.name ...component.params}}
    {{/each}}
  9. chriskrycho commented on Sep 16, 2019

    @chriskrycho
    Contributor

    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.

  10. algodave commented on May 9, 2021

    @algodave

    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 🙂

  11. sly7-7 commented on Apr 21, 2022

    @sly7-7

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

  12. wagenet commented on Jul 23, 2022

    @wagenet
    Member

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

  13. NullVoxPopuli commented on Nov 20, 2024

    @NullVoxPopuli
    SponsorContributor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions