1

I'm trying to understand certain peculiarity.

Setting xxx property and iterating #each in one controller works, while seemingly same operation with yyy #each doesn't...

I'm including highlights of the code and the runnable code snippet:


App.IndexController = Ember.Controller.extend({
  xxx : [{name:"a"}, {name:"b"}], // this works just fine
});  

{{#each item in xxx}}
  <li>{{item.name}}</li>
{{/each}}

App.ColorController = Ember.Controller.extend({
  yyy : [{name:"c"}, {name:"d"}], // this triggers deprecation
  // You attempted to access `yyy` from ...
  // But object proxying is deprecated. Please use `model.yyy` instead
});

{{#each item in yyy}}
  <li>{{item.name}}</li>
{{/each}}

App = Ember.Application.create();

    App.Color = DS.Model.extend({
      name: DS.attr('string')
    });
    
    App.Router.map(function() {
      this.resource('color', function(){
        this.route('show', { path: ':color_id' });
      });
    });

    App.IndexRoute = Ember.Route.extend({
      
      model: function() {
        return [
                { id: 1, name: "Red" },
                { id: 2, name: "Blue" },
               ];
      }
    });   

    App.IndexController = Ember.Controller.extend({
      xxx : [{name:"a"}, {name:"b"}], // this works just fine
    });     

    App.ColorController = Ember.Controller.extend({
      init : function() {
        this._super();
        console.info("Just to double check, this controller gets initialised");
      },
      yyy : [{name:"c"}, {name:"d"}], // this triggers deprecation
      // You attempted to access `yyy` from ...
      // But object proxying is deprecated. Please use `model.yyy` instead
    });
<script type="text/x-handlebars">
    <h2>Ember Starter Kit</h2>
    {{outlet}}
  </script>
 
  <script type="text/x-handlebars" id="index">
    <h3>Index</h3>
    <ul>
      {{#each color in model}}
        <li>{{#link-to "color.show" color}} {{color.name}} {{/link-to}}</li>
      {{/each}}
    </ul>
    <ul>
      {{#each item in xxx}}
        <li>{{item.name}}</li>
      {{/each}}
    </ul>
   </script>

  <script type="text/x-handlebars" id="color/show">
    <h3>color/show</h3>
    <h4>{{ model.name }}</h4>
    <ul>
      {{#each item in yyy}}
        <li>{{item.name}}</li>
      {{/each}}
    </ul>
    {{#link-to "application"}}Go back to the list{{/link-to}}
  </script>
 
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
  <script src="http://builds.emberjs.com/tags/v1.13.2/ember.debug.js"></script>
  <script src="http://builds.emberjs.com/tags/v1.13.2/ember-template-compiler.js"></script>
  <script src="http://builds.emberjs.com/tags/v1.13.2/ember-data.js"></script>

I'd like to learn more:

  • why it works in one case and doesn't work in another?
  • what is the Ember way of fixing it?

EDIT: Updated code snippet include Color model. To trigger deprecation warning click on one of the colours (Red, Blue)... This is what happens when I run the snippet:

enter image description here

Mars Robertson
  • 12,673
  • 11
  • 68
  • 89
  • Your snippet doesn't trigger object proxying deprecation. Also, you didn't include declaration of `Color` model. – Daniel Kmak Jun 20 '15 at 09:44
  • Thank you @Daniel - I've included ```Color``` model (should that matter?) and included a screenshot presenting Deprecation warning. My question is still valid - ```controller.xxx``` works while ```controller.yyy``` doesn't... – Mars Robertson Jun 20 '15 at 10:45

1 Answers1

2

Okay, as I expected - problem lies in naming conventions and relics of the past(ObjectController). Declaring ColorController creates controller for model, not a route. You need here controller for route, so changing ColorController to ColorShowController solves problem and values render. Deprecation's gone.

App = Ember.Application.create();

    App.Color = DS.Model.extend({
      name: DS.attr('string')
    });
    
    App.Router.map(function() {
      this.resource('color', function(){
        this.route('show', { path: ':color_id' });
      });
    });

    App.IndexRoute = Ember.Route.extend({
      
      model: function() {
        return [
                { id: 1, name: "Red" },
                { id: 2, name: "Blue" },
               ];
      }
    });   

    App.IndexController = Ember.Controller.extend({
      xxx : [{name:"a"}, {name:"b"}], // this works just fine
    });     

    App.ColorShowController = Ember.Controller.extend({
      init : function() {
        this._super();
        console.info("Just to double check, this controller gets initialised");
      },
      yyy : [{name:"c"}, {name:"d"}], // this triggers deprecation
      // You attempted to access `yyy` from ...
      // But object proxying is deprecated. Please use `model.yyy` instead
    });
<script type="text/x-handlebars">
    <h2>Ember Starter Kit</h2>
    {{outlet}}
  </script>
 
  <script type="text/x-handlebars" id="index">
    <h3>Index</h3>
    <ul>
      {{#each color in model}}
        <li>{{#link-to "color.show" color}} {{color.name}} {{/link-to}}</li>
      {{/each}}
    </ul>
    <ul>
      {{#each item in xxx}}
        <li>{{item.name}}</li>
      {{/each}}
    </ul>
   </script>

  <script type="text/x-handlebars" id="color/show">
    <h3>color/show</h3>
    <h4>{{ model.name }}</h4>
    <ul>
      {{#each item in yyy}}
        <li>{{item.name}}</li>
      {{/each}}
    </ul>
    {{#link-to "application"}}Go back to the list{{/link-to}}
  </script>
 
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
  <script src="http://builds.emberjs.com/tags/v1.13.2/ember.debug.js"></script>
  <script src="http://builds.emberjs.com/tags/v1.13.2/ember-template-compiler.js"></script>
  <script src="http://builds.emberjs.com/tags/v1.13.2/ember-data.js"></script>
Daniel Kmak
  • 18,164
  • 7
  • 66
  • 89
  • To any editors which change my explanation - I'm sure about what I write and I don't mean `color` route, but `color` as model. Please read more about `ObjectController` and how it works in practice. – Daniel Kmak Jun 20 '15 at 18:36
  • If this would be controller only for `color` route, then why would it raise deprecation, COMING FROM CONTROLLER, in `color.show` route? ; ) – Daniel Kmak Jun 20 '15 at 18:38
  • 1
    What is actually happening is that ColorController sets the controller for ColorRoute, and thus Ember is left to generate a controller for ColorShowRoute. Ember will generate an ObjectController or ArrayController depending on what is returned from the model hook, and that's where the deprecation warning comes from. P.S. ember-cli 0.2.7 includes an addon that disables the generation of proxy controllers. – locks Jun 20 '15 at 20:11
  • @locks Okay, I think you're right. Thanks for explanation! – Daniel Kmak Jun 20 '15 at 20:59
  • Thank you @Daniel, thank you all. I'm using CLI in the project at work, but in order to standalone test case I had to create non-CLI template - http://discuss.emberjs.com/t/is-there-a-recommended-js-bin-plunker-jsfiddle-template-when-asking-for-help/8222 - and as I was doing this I've encountered this peculiarity (which seems obvious once you know it). – Mars Robertson Jun 20 '15 at 22:04