Reputation: 2434
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.
Upvotes: 1
Views: 11687
Reputation: 3807
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>
Upvotes: 0
Reputation: 77904
From your example you passed 2 parameters to PropertyDb.getProperties
:
postcode
Object: {postcode : 'CC11CC'}
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");
}
);
},
/*...*/
}
});
Upvotes: 6
Reputation: 48972
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");
}
);
},
Upvotes: 1