Search code examples
backbone.js

Backbone.js sync() can't find the url property


With this contrived example code:

var Product = Backbone.Model.extend({
  idAttribute: '_id',
  url: '/rest/product',
});

var Cart = Backbone.Collection.extend({
  model: Product,
  url: '/rest/cart',
});

p1 = new Product({name: 'Keyboard'});
p2 = new Product({name: 'Mouse'});

c = new Cart();
c.add([p1, p2]);
c.sync();

I see Error: A "url" property or function must be specified There are tons of posts revolving around this same error message, but all the ones I've found are the result of, aptly, not having a url property or function defined somewhere along the way.

I feel as if I've missed a linking step somewhere - maybe I'm implicitly relying on a "magic" connection/callback/property/attribute that Backbone.js doesn't actually set automatically?


Solution

  • I'd first take a step back and examine your use case and the schema you have chose. You're clearly trying to add products to a user's shopping cart.

    The issue I see is that you've made the cart a collection. I'd suggest making cart a model that contains a collection of products.

    var ProductCollection = Backbone.Collection.extend({
        model : Product
    });
    
    var Cart = Backbone.Model.extend({
        url : '/rest/cart',
        defaults : {
            products : new ProductCollection()
        }
    });
    

    With this new schema, you can do:

    var c = new Cart();
    c.get('products').add([p1, p2]);
    c.save();
    

    An added benefit of this schema is that you can include additional data attributes to your cart, such as the customer ID, when the cart was created, etc.