3

I have a simple application with a model, route and controller. I can't access the data from the model in my controller. I use ember-cli so I have the following structure:

/app/router.js

var Router = Ember.Router.extend({
  location: config.locationType
});
Router.map(function() {
  this.route('logs',{path: '/'});
});
export default Router;

/app/routes/logs.js

export default Ember.Route.extend({
  controllerName: 'logs',
  model: function() {
    return this.store.find('logs');
  }
});

/app/models/logs.js

export default DS.Model.extend({
  ip: DS.attr('string'),
  timestamp: DS.attr('number'),
  visited_resource: DS.attr('string'),
  pretty_string: DS.attr('string')
});

/app/controllers/logs.js

export default Ember.Controller.extend({
  url: function() {
    var model = this.get('model');
    var basePath = "http://example.com";
    var path = model.visited_resource;
    return basePath+path
  }.property('visited_resource')
});

My problem is that the model.visited_resources, or this.get('model.visited_resources') or this.get('model.[any param]') is undefined.

If I log the whole model object and inspect it, all my data is there! ! https://i.sstatic.net/nkvyT.png

It's just that the controller can't access it. What am I doing wrong?

1
  • 1
    Your model is an array thus your logs controller should be extended from ArrayController and every thing will fall into place. Commented Jul 13, 2015 at 7:08

1 Answer 1

3

Your model is an array from looking at that screenshot (content: Array[5]), so you need to get the first object if you want a single item:

export default Ember.Controller.extend({
  url: Ember.computed('model', function() {
    var logs = this.get('model');
    var firstLog = logs.get('firstObject');
    var path = firstLog.get('visited_resource');
    var basePath = 'http://example.com';
    return basePath + path; 
  });
});

or iterate over each item and return an array:

export default Ember.Controller.extend({
  urls: Ember.computed('model', function() {
    var logs = this.get('model');
    var basePath = 'http://example.com';
    var urls = logs.map(function(model) {
      var path = model.get('visited_resource');
      return basePath + path;
    });
    return urls;
   })
});

To create a computed property on the model, then do it on the model:

export default DS.Model.extend({
  ip: DS.attr('string'),
  timestamp: DS.attr('number'),
  visited_resource: DS.attr('string'),
  pretty_string: DS.attr('string'),
  url: Ember.computed('visited_resource', function() {
    var basePath = 'http://example.com';
    var path = this.get('visited_resource');
    return basePath + path;
  })
});

and you'll be to access the url property like any other property:

   export default Ember.Controller.extend({
      url: Ember.computed('model', function() {
        var logs = this.get('model');
        var firstLog = logs.get('firstObject');
        return firstLog.get('url');
      })
    })

You can also explicitly set the model using setupController:

export default Ember.Route.extend({
  controllerName: 'logs',
  model: function() {
    return this.store.find('logs');
  },
  setupController: function(controller, model) {
    controller.set('model', model);

    // or first item only
    controller.set('model', model.get('firstObject'));
  }
});
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks! I totally thought wrong about how it worked. I changed it to become an ArrayController instead. I'm now trying to make the whole ObjectController thingy work. Thanks again!
@FilipNilsson ObjectController and ArrayController are going to become Deprecated. Use just Controller. emberjs.com/deprecations/v1.x/#toc_objectcontroller

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.