thyforhtian
thyforhtian

Reputation: 366

Emberjs + data + rails - Uncaught TypeError: Cannot call method 'map' of undefined

When I am trying to load data from rails db with emberjs + ember data I am getting this error

Uncaught TypeError: Cannot call method 'map' of undefined

Here's the coffescript code:

window.Cosmetics = Ember.Application.create

Cosmetics.store = DS.Store.create
  revision: 4
  adapter: DS.RESTAdapter.create 
    bulkCommit: false

Cosmetics.admin_user = DS.Model.extend({
  name: DS.attr('string')
  email: DS.attr('string')
});

Cosmetics.view = Ember.View.extend
  templateName: 'ember/views/aaa'

Cosmetics.admin_user.reopenClass
  url: 'admin/user'

Cosmetics.store.findAll(Cosmetics.admin_user)

Controller gets proper JSON data. I've tried mapping the code from the examples found over the internet but nothing helped. Any ideas? I guess I'm doing sth wrong. Thanks in advance for any help.

Upvotes: 6

Views: 3977

Answers (5)

tomaszbak
tomaszbak

Reputation: 8287

The root cause of the problem is pluralize function in rest_adapter.js therefore the solution is to fix it ;)

  DS.RESTAdapter.reopenClass({
    pluralize: function(name) {
      if (!this.plurals[name])
        name = name.substring(name.lastIndexOf('/')+1);

      return this.plurals[name] || name + "s";
    }
  });

Upvotes: 0

Akshay Rawat
Akshay Rawat

Reputation: 4784

Found the problem, not sure about the solution.

If your resource is being served under a namespace, eg

App.Event = DS.Model.extend({
  name: DS.attr('string'),
});

App.Event.reopenClass({
  url: 'api/event'
})

When ember-data parses the json response, it does something like json[plural] in findAll which should be json['events'], however the plural is calculated to be json['api/events'], and hence the error. I'll ask around and probably raise a ticket for this.

Update

I've created a ticket for this here

Workaround

As a hack, I'm doing this:

def index
  respond_to do |format|
    format.json { render json: { 'api/events': Event.all } }
  end
end

Upvotes: 4

thyforhtian
thyforhtian

Reputation: 366

I've finally found the solution!

I'm not sure if this should be done this way but it was enough to get rid of bulk commits. So what the store should look like is:

Cosmetics.store = DS.Store.create
  revision: 4
  adapter: DS.RESTAdapter.create 

bulkCommit: false was causing the Uncaught TypeError: Cannot call method 'map' of undefined error.

This problem seems to be related only to ember-data when used in rails apps.

I seem to have rushed a little bit as what seemed to solve the problem, caused anothers ;|

Upvotes: 0

Andre Bernardes
Andre Bernardes

Reputation: 1623

I had the exactly same problem. What solved it for me was adding the root node when rendering the JSON in the index action in my controller. That meant changing this line:

format.json { render json: @things }

to this:

format.json { render json: { things: @things }}

That's because Ember-data requires the root node in the JSON object, but Rails doesn't include it by default.

I hope that helps.

Upvotes: 4

tvon
tvon

Reputation: 1513

ember-data expects findAll results to be nested under the pluralized form of the model:

What ember-data is expecting:

{
    "users": [
        {
            "activated": null, 
            "created_at": "2012-05-14T19:35:44Z", 
            "email": "[email protected]", 
            "id": 1, 
            "name": "john doe", 
            "updated_at": "2012-05-15T20:23:06Z"
        }
    ]
}

What it is getting in your example:

[
    {
        "activated": null, 
        "created_at": "2012-05-14T19:35:44Z", 
        "email": "[email protected]", 
        "id": 1, 
        "name": "john doe", 
        "updated_at": "2012-05-15T20:23:06Z"
    }
]

Specifically, the error comes from ember taking the JSON response and running "map" over everything under the "users" key, which in your case does not exist, hence "map" is being called on "undefined".

Upvotes: 3

Related Questions