1
votes

I am currently working on the framework for a project that we have split into a web client and server code. The client code uses a combination of require .js and backbone.js. I'm currently working on setting up the client/server communication, and ideally we'd like to be able to use backbone’s built in .sync functionality (and the fetch call built off of it) .

However, I'm running into an odd series of errors.

As the code executes, I'm getting the following error in the console. "Uncaught Error: A "url" property or function must be specified"

These are the related shims from our main.js

require.config({
    paths: {
        'jQueryBase': '../vendor/jquery-1.10.2/jquery-1.10.2',
        'jQuery': '../vendor/jquery-ui-1.10.3/ui/jquery-ui',
        'underscore': '../vendor/underscore/underscore',
        'backbone': '../vendor/backbone/backbone',
        'handlebars': '../vendor/handlebars/handlebars-v1.1.2 '
    },
    shim: {
        'jQuery': {
            exports: '$',
            deps: ['jQueryBase']
        },
        'underscore': {
            exports: '_'
        },
        'backbone': {
            exports: 'Backbone',
            deps: ['underscore', 'jQueryBase']
        },
        'handlebars': {
            exports: 'Handlebars'
        }
    },
    waitSeconds: 0
});

This is our dogModel.js

define(['backbone'],
    function (Backbone) var DogModel = Backbone.Model.extend({

    });

    return DogModel;
});

This is our dogCollection.js

define {
    ('backbone',
        '../models/dogModel'
        J,
        function (Backbone,
            DogModel) {

            var DogCollection = Backbone.Collection.extend({
                model: DogModel,
                url: '/dogs',
            });

            return DogCollection;
        });

This is our dogData.js

define(['../collections/dogCollection',
        '../models/dogModel'
    ],
    function (DogCollection,
        DogModel) {

        var dogDataModule = {};

        dogDataModule.dogList = new DogCollection();

        //this request works
        $.ajax(
            type: "GET",
            dataType: "json",
            url: "http://localhost:7001/SERVICES/dogs",
            success: function (data) {
                dogDataArray = data;

                for (var i = 0; i < dogDataArray.length; i++) {
                    var dogData = dogDataArray[i];
                    var dogModel = new DogModel();
                    dogModel.set(dogData);
                    dogDataModule.dogList.add(dogModel);
                }
            }
        });

    //this request doesn't
    dogDataModule.dogList.sync('read', DogCollection, {
            success: function () {
                alert("success ");
            },
            error: function () {
                alert("failure ");
            }
        };

        return dogDataModule;
    });

I've attempted to add a URL to directly to the options of the sync request, as so:

dogDataModule.dogList.sync('read', DogCollection, {
        url: 'http://localhost:7001/SERVICES/dogs',
        success: function () {
            alert("success");
        },
        error: function () {
            alert("failure "
            };
        });

But all this does is change the error to read "Uncaught TypeError : Object function (){ return parent.apply(this, arguments); } has no method 'trigger'".

I've also attempted to add "SERVICES/" and "../SERVICES/" in front of the collection's url property, or giving the full and explicit URL property (up to and including http://), but none of that has worked either.

Can anyone help me figure out why I am seeing this error?

1

1 Answers

2
votes

First of all, I don't think there's any reason for you to call dogList.sync directly (you could use dogList.fetch, you certainly want the features fetch offers you in addition to the server call.

Now, your error comes from the fact that you use sync incorrectly. The second argument is intended to be an instance of a collection, not a class, as shown in fetch's code:

return this.sync('read', this, options);

So in your case, that'd be:

dogDataModule.dogList.sync('read', dogDataModule.dogList

Bonus:

The error Uncaught TypeError : Object function (){ return parent.apply(this, arguments); } has no method 'trigger comes from the fact that Backbone's trying to apply the method trigger of your class instead of an instance. The function (){ return parent.apply(this, arguments); } part is the constructor of your class, so that gives you a hint of what's happening.