Pregunta

I'm fairly new to Angular but am trying to abstract a RESTful call from $http to a factory/resource but I cant seem to pass any params to it. I've read though SO but cannot find an example of this.

My factory code (services.js):

myApp.factory("PropertyDb", function($resource, $log) {
return {
    getProperties: function(onSuccess) {
        var properties = $resource("http://myurl.com/get_properties.php?", {
            callback: 'JSON_CALLBACK',
            postcode: 'AA11AA',
            minimum_beds: '3',
            minimum_price: '97500'
        }, 

        {
            fetch : {method:'JSONP'},
            params: {postcode: 'BB11BB'} // This doesn't override the above or work without the above postcode

        });

        properties.fetch(
            function success(response) {
                console.log(response);
                onSuccess(response.listing);
            }, 
            function error(response) {
                console.log(response);
                console.log("error");
            }
        );
    },

My Controller code:

myControllers.controller('PropertyListCtrl', ['$scope', 'PropertyDb',
function($scope, PropertyDb) {

    $scope.properties = {};

    // Adding the postcode below doesnt work...
    PropertyDb.getProperties({postcode : 'CC11CC'}, function(responce) {
        $scope.properties = responce;
    });

}]);

I want to be able to use my factory in my controllers and pass it different params like postcode etc and override the defaults set in the factory. No matter what I try I cannot seem to do this and the docs aren't very easy to follow.

¿Fue útil?

Solución

From your example you passed 2 parameters to PropertyDb.getProperties:

  • postcode Object: {postcode : 'CC11CC'}
  • callback: function(responce) {$scope.properties = responce;}

The one thing is to use 1st parameter in factory:

myApp.factory("PropertyDb", function($resource, $log) {
return {
    getProperties: function(parameter, onSuccess) {
    //                       ^param^ , ^callback^         

    /* ...  */
    }

So fixed version of service should be:

myApp.factory("PropertyDb", function($resource, $log) {
return {
    getProperties: function(parameter, onSuccess) {
        var properties = $resource("http://myurl.com/get_properties.php?", {
            callback: 'JSON_CALLBACK',
            postcode: parameter.postcode,
            minimum_beds: '3',
            minimum_price: '97500'
        }, 

        {
            fetch : {method:'JSONP'},
            params:  parameter 
        });

        properties.fetch(
            function success(response) {
                console.log(response);
                onSuccess(response.listing);
            }, 
            function error(response) {
                console.log(response);
                console.log("error");
            }
        );
    },
     /*...*/
   }
});

Otros consejos

Try:

myApp.factory("PropertyDb", function($resource, $log) {
return {
    getProperties: function(data,onSuccess) { //add 1 more parameter
        var properties = $resource("http://myurl.com/get_properties.php?", {
            callback: 'JSON_CALLBACK',
            postcode: 'AA11AA',
            minimum_beds: '3',
            minimum_price: '97500'
        }, 
        {  //fix your code here
            fetch : {
             params: data || {postcode: 'BB11BB'},
             method:'JSONP'
            }
        });

        properties.fetch(
            function success(response) {
                console.log(response);
                onSuccess(response.listing);
            }, 
            function error(response) {
                console.log(response);
                console.log("error");
            }
        );
    },

But I think a better solution is we only define the $resource once:

myApp.factory("PropertyDb", function($resource, $log) {
    //define only once here so we don't need to redefine it whenever we run the method.
    var properties = $resource("http://myurl.com/get_properties.php?", {
                callback: 'JSON_CALLBACK',
                postcode: 'AA11AA',
                minimum_beds: '3',
                minimum_price: '97500'
            }, 
            {  //fix your code here
                fetch : {
                 params: {postcode: 'BB11BB'},
                 method:'JSONP'
                }
            });

    return {
        getProperties: function(data,onSuccess) { //add 1 more parameter

            properties.fetch(
                data, //send the data.
                function success(response) {
                    console.log(response);
                    onSuccess(response.listing);
                }, 
                function error(response) {
                    console.log(response);
                    console.log("error");
                }
            );
        },

I got it, you can use app.factory() as a separate js file to read a file, say get_data.js. The parameter arg is a file path(now is a web file, you can change it to a relative file path, like js/abc.txt).

var app = angular.module('app', []);

// this part can separate from others as a single file - get_data.js
app.factory('metdata', ['$http', function ($http) {
  var load_data = {};  // This is like a new class in factory
  load_data.getDataPath = function (arg) {  // This is like a method of class
    console.log(arg);
    load_data.path = arg;  // This is like a attribute of class
      return $http.get(load_data.path);
  };
  console.log('print 1 ' + load_data.data);

  return load_data;  // Call the class, and then call getDataPath function

}]); 

app.controller('MainCtrl', ['$scope', 'metdata', function($scope, metdata) {
  $scope.loadData = function () {
    var dataPath = 'https://raw.githubusercontent.com/OnlyBelter/learnGit/master/readme.txt';
    metdata.getDataPath(dataPath).success(function (data) {
      console.log(data);
    });
  };
}]);
<!--this is html file-->
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.js"></script>
<body ng-app="app" ng-controller="MainCtrl">
    <br>
    <div>
        <p>Load data:
            <button ng-click="loadData()">Load</button>
        </p>
    </div>
</body>

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top