1

I know I'm just missing something simple here but the following does not seem to work.

App.Storage = Ember.Object.extend

  push: (key, data)-> #I want to call this from the loop below in pushMany
    #...
    #...

  pushMany: (key, data)->

    data.forEach (d)->
      #Tried:
      @push(key, d) #<< TypeError: undefined is not a function
      #Also tried:
      @send('push', key, d) #<< TypeError: undefined is not a function
      #Also tried:
      App.Storage.push(key, d) #<< TypeError: undefined is not a function

I am calling the pushMany in a route:

App.MessagesRoute = Ember.Route.extend
  setupController: (controller, model)->
    #storage is injected to route
    #I can call storage.push here so I'm pretty sure my injection is working properly
    storage = @get('storage')
    storage.pushMany 'message', [{id: 3, value: 'Test Msg', author: 'Jules'}, {id: 4, value: 'Hello World!', author: 'Jules'}]

Been stuck for hours now. Any help would be appreciated.

Jay-Ar Polidario
  • 6,463
  • 14
  • 28

3 Answers3

1

Your problem is the object scope.

Here an example:

var Test = Ember.Obejct.extend({
  func: function(){
    // the scope of "this" is the Test object
    this.get('data');

    var self = this;

    this.get('data').forEach(function(){
      // "this" is now the closure
      // use "self" to access it
      self.set('data', 'blup');

    });
  }        
});

Your case:

App.Storage = Ember.Object.extend
  pushMany: (key, data)->
     self = this
     data.forEach (d)->
      self.push(key, d)

See here: How do JavaScript closures work?

Community
  • 1
  • 1
medokin
  • 610
  • 9
  • 21
  • Hmm... I'm not trying to `set` let alone `access` `data` as `data` and `key` are function parameters in my pushMany function. What I want to access is the function `push` when inside the function `pushMany` Or did I misundertand what you wanted to explain? – Jay-Ar Polidario Apr 15 '14 at 11:24
  • Added your case to my answer. – medokin Apr 15 '14 at 11:35
  • Works like magic! :D I never used `self = this` and just use `this` always, so that's how to use it properly. Thanks! :D – Jay-Ar Polidario Apr 15 '14 at 11:41
  • 1
    Yes, but be careful with scopes in closures. this != this :) – medokin Apr 15 '14 at 11:43
0

The issue is that you're working very outside of the Ember way. Instead of using a App.Storage to store your values, just do it in the model hook:

App.MessageRoute = Ember.Route.extend({
    model:function() {
       return [{id: 3, value: 'Test Msg', author: 'Jules'}, {id: 4, value: 'Hello World!', author: 'Jules'}]
   },
   actions: {
       addMessage:function() {
           this.get('model').pushObjects({id:5,value:'Heya',author:'Nick'});
       }
   }
});
NicholasJohn16
  • 2,390
  • 2
  • 21
  • 45
  • 1
    I'm sorry you misunderstood. As I just really wanted to know how to call the 'push' method, I tried to omit other unnecessary details such as that I am using HTML5 localStorage for App.Storage for caching of messages. Therefore, I cannot use this approach of yours. But thanks for the reply. – Jay-Ar Polidario Apr 14 '14 at 22:00
0

This thread is not so recent but for future travellers reference:

I had the same issue (I am also using CoffeeScript as the author) and figured out that:

The issue is the fact that he is using data.forEach (d)->:

This will be "compiled" into the following, meaning that this is the scope of the forEach() method:

data.forEach(function(d) {
  this.push(key, d);
  this.send('push', key, d);
  return App.Storage.push(key, d);
});

When actually, it should be "compiled" into something like this:

  this.data.forEach((function(_this) {
    function(d) {
      // your code here, using '_this' and 'd'

      _this.push(key, d);
      _this.send('push', key, d);
      return App.Storage.push(key, d);

    };
  })(this));

Helpful resources:

biker856
  • 327
  • 1
  • 4
  • 9