Dynamic template arguments for an Ember component

I’ve run into a situation with a glimmer component that renders a LinkTo component within. The issue is that LinkTo treats the case where @model={{undefined}} and the case of omitting the @model argument as 2 different cases. This is because the default value for it is a special value of UNDEFINED. When this happens the component uses JS to make the transition i.e. the href is # and so you can’t use browser commands like Open in new tab to open the resulting link. So I tried using inline ifs

    <LinkTo @route={{@route}}
    {{if @model (concat "@model={{" @model "}}")}}
    {{if @query (concat "@query={{" @query "}}")}}
    >
    {{yield}}
    </LinkTo>

however, much as I expected this does not work. I’ve had to resort to having multiple if blocks like so:

    {{#if @model}}
      <LinkTo @route={{@route}} @model={{@model}} @query={{@query}} @replace={{@replace}}>
        {{yield}}
      </LinkTo>
    {{else if @models}}
      <LinkTo @route={{@route}} @models={{@models}} @query={{@query}} @replace={{@replace}}>
        {{yield}}
      </LinkTo>
    {{else}}
      <LinkTo @route={{@route}} @query={{@query}} @replace={{@replace}}>
        {{yield}}
      </LinkTo>
    {{/if}}

This works, but is rather verbose and requires a lot of duplication. Is there a way to dynamically pass @model only when it is specified to the parent component?

Answer

I think what you should do is always to rely on @models.

You could do this:

<LinkTo @route={{@route}} @models={{this.models}}>{{yield}}</LinkTo>

and in js:

get models() {
  if(this.args.model) {
    return [this.args.model];
  }
  if(this.args.models) {
    return this.args.models;
  }
  return [];
}

Leave a Reply

Your email address will not be published. Required fields are marked *