0

I have a model that extends Backbone.RelationalModel and that has a one to many relation, the problem occurs when I try to send an ajax request with that model as the parameter.

$.ajax(
        url: 'save'
        type: 'POST'
        data:
          project: MyApp.project
      )

I get the following error Uncaught TypeError: Cannot read property '_permitsAvailable' of undefined it occurs in the method named acquire Could anyone tell me why this is happening ?

EDIT:

after digging for the cause of the error, I found that jQuery.param function defines add(key, value) function, at some point this value attribute is acquire function, this function will have no this, so I get the error, I don't know why _queue of Backbone.RelationalModel gets serialized ?

Khaled
  • 2,101
  • 1
  • 18
  • 26

1 Answers1

0

I don't know why that is happening. Here's some info that may help you solve the problem, though:

The acquire method is part of Backbone.Semaphore, which is a mixin that's used for queue and concurrency management within Backbone.Relational. The semaphore mixin is mixed into a few different classes, including the RelationalModel.

The private _permitsAvailable property only is accessed within the mixin itself, using this._permitsAvailable. Your error message tells you that the error occurs, because this is undefined. This can only ever happen when a method is executed with Function.call or Function.apply.

Edit: The issue seems to be that jQuery is trying to serialize the model by iterating each of it's properties, and if the property is a function, calling that function and serializing its return value. This is a no-go for Backbone models, because the data attributes aren't actually on the model object, but stored in the Model.attributes property.

This problem should be easily fixed by converting the model object to a more serialization-friendly format using the Model.toJSON method :

$.ajax(
  url: 'save'
  type: 'POST'
  data:
    project: MyApp.project.toJSON()
)

Quoting from the Model.toJSON documentation:

Return a copy of the model's attributes for JSON stringification. This can be used for persistence, serialization, or for augmentation before being sent to the server. The name of this method is a bit confusing, as it doesn't actually return a JSON string — but I'm afraid that it's the way that the JavaScript API for JSON.stringify works.

You must also make sure that includeInJSON option in reverseRelation for backbone-relational is set to false to avoid serializing the related models in your model.attributes.

jevakallio
  • 35,324
  • 3
  • 105
  • 112
  • you are right, the function gets called without a context from the `jQuery.param` function, I added some info to the question. – Khaled Feb 04 '13 at 09:26
  • Thanks I had to remove the models from the attributes as I was using backbone relational, I added this to your answer if you don't mind. – Khaled Feb 04 '13 at 09:49