How to stop Ember Render complaining about deprecated quoteless parameters when using call()?

I am following a template for dynamically choosing which model, route, controller to render with a render helper, as outlined in this question (and elsewhere). My problem is that we want to run with the Ember.ENV.RAISE_ON_DEPRECATION flag set, to catch problems before they develop into upgrade nightmares. I am calling Ember.Render from a handlebars helper, like this:

Ember.Handlebars.registerBoundHelper('renderModuleEdit', function(callingContext, module, options) {
  var modelName = callingContext.get('type').get('modelName');
  return Ember.Handlebars.helpers.render.call(callingContext, "edit_" + modelName, modelName, options);
});

The template has this code in it:

{{#each module in modules}}
  <div class="tab-content" {{bind-attr class="module.active:active"}}>
    {{renderModuleEdit module module}}
  </div>
{{/each}}

The problem is that render fails on the test for ā€˜quoteless parametersā€™, even though Iā€™m using call() on it, rather than a direct handlebars template syntax. The test is defined in the source on this line. The actual test is options.types[0] !== 'IDā€™, and while the options parameter is available in the register helper function (first code block above), and thus I would be able to change the 1st type away from 'ID', Iā€™m not sure what I can change it to that wouldnā€™t cause something else to subtly break later. The error message comes through as:

Uncaught Error: Using a quoteless parameter with {{render}} is deprecated. Please update to quoted usage '{{render ā€œedit_Introā€}}.

As I am not using {{render edit_Intro}} to make this call, I have no idea how to correct this. If I change the template code to {{renderModuleEdit ā€˜moduleā€™ ā€˜moduleā€™}}, then the parameters to my renderModuleEdit come through as strings of ā€˜moduleā€™ rather than the model instance I need.

I feel like I have no understanding of what this test is actually for and what the ā€˜quotelessā€™ vs ā€˜quotedā€™ parameters even mean. Can someone explain this? Is there a way around this deprecation warning for calling render from a registered bound handlebars helper like this?

I am cross posting this from StackOverflow because, the more I think about it, this is not a straightforward ā€œpractical, answerableā€ question. Itā€™s a pretty in-depth, advanced usage causing the conflict between the render helper and the environment flag.

1 Like

Anyone? Iā€™ve the same issue and it would be great if thereā€™s a clean solution for this.

Is this a solution? Havenā€™t tried it yet.

Iā€™ve upvoted that question before, and I remember it contributing to my prototyping. I think it would work if you componetize all of your editor fields, but I shied away from that for now. Our project has been embracing components, so I may try to take that approach in the future. However, for the initial release of our project, we went with a list of static options rather than a truly dynamic list. So instead of the #each in the code before, we have a set of static templates that look like this:

{{#tab-view}}
  {{#tab-pane name="Intro"}}
    {{intro-edit-form intro=introModule}}
  {{/tab-pane}}

  {{#tab-pane name="IV"}}
    {{iv-edit-form iv=ivModule}}
  {{/tab-pane}}
{{/tab-view}}

This is a kludge, and will become very burdensome in the future. But for churning out the initial set of templates we need to support, it was an easy copy/paste job that got us past this road block. As you can see, the -edit-forms have been componetized themselves, but Iā€™ve not gone back to revisit a bound helper that can dynamically choose which component to call.

Any solution for that ?

I updated my helper to the following, where the content object is my specific polymorphic model:

import Ember from "ember";

export default Ember.Handlebars.makeBoundHelper(function(content, options) {
  var args = Array.prototype.slice.call(arguments, 1);
  var contentType = content.get('contentType');
  var contentName = content.get('contentName');

  options.types = ['STRING', 'ID'];
  options.contexts = [this, this];
  args.unshift('content.' + contentName);
  args.unshift(contentType);

  return Ember.Handlebars.helpers['render'].apply(this, args);
});