Search code examples
javascriptangularjsngresource

Issues using $resource without the new operator


I'm trying to use Angular promise API in my app. And I was a little confused. I created a factory like in code below

factory('transport', function ($resource) {
    var baseUrl = "http://aw353/WebServer/odata/Payments";
    return $resource("", {},
        {
            'getAll': { method: "GET",params: {svcUrl:"@svcUrl"}, url: baseUrl + ":svcUrl" },
            'save': { method: "POST", params: {svcUrl:"@svcUrl"}, url: baseUrl+ "(:svcUrl)" },
            'update': { method: 'PUT', params: {svcUrl:"@svcUrl", key: "@key" }, url: baseUrl+ "(:svcUrl)" + "(:key)"},
            'query': { method: 'GET', params: {svcUrl:"@svcUrl", key: "@key" }, url: baseUrl +"(:svcUrl)" + "(:key)"},
            'remove': { method: 'DELETE',  params: {svcUrl:"@svcUrl", key: "@key" }, url: baseUrl + "(:svcUrl)" + "(:key)"}
        });
});

I'm using this factory in controller and when I implement the function like this

var getData = function () {
    (transport()).$getAll({svcUrl:"//BasicSettings"})
        .then(function (data) {
            $scope.DataSource = data.value[0];
            console.log($scope.DataSource.SystemName);
        });
}();

it fails and I get error "Cannot read property '$getAll' of undefined"
But when I use 'new' keyword like this

var getData = function () {
    (new transport()).$getAll({svcUrl:"//BasicSettings"})
        .then(function (data) {
            $scope.DataSource = data.value[0];
            console.log($scope.DataSource.SystemName);
        });
}();

it works.

I know the difference between constructor function and usual function. But I don't understand why promise API works only in second case.
Can anyone help me to understand how it works?


Solution

  • Try

    transport.getAll(...).$promise.then(...)
    

    instead.

    I know the difference between constructor function and usual function. But I don't understand why promise API works only in second case.

    well because the API is designed that way.You have instance methods and class methods.

    To create an instance you need the new operator and then you get access to instance methods.

    The $resoure() method is a factory to extend "$resource" and returns a constructor function ,that has class methods,and instances of the that constructor function have instance methods.

    function Resource(value) {
        shallowClearAndCopy(value || {}, this);
    }
    
    forEach(actions, function (action, name) {
        var hasBody = /^(POST|PUT|PATCH)$/i.test(action.method);
    
        Resource[name] = function (a1, a2, a3, a4) {
            var params = {}, data, success, error;
    (...)
    

    A simple click on view source in the doc shows that class methods are created ADHOC on Resource constructor

    https://github.com/angular/angular.js/blob/master/src/ngResource/resource.js#L492