Reputation: 1449
I am using an angular factory to perform CRUD on my classes on Parse.com. I have a total of 4 classes and need to perform create, get, put, delete on all 4. Although the URL is different for each one everything else remains the same. Can I pass variables to the factory to change the class name in the api URL?
Here is an example of one factory.
.factory('Programme',['$http','PARSE_CREDENTIALS',function($http,PARSE_CREDENTIALS){
return {
getAll:function(){
return $http.get('https://api.parse.com/1/classes/Programme',{
headers:{
'X-Parse-Application-Id': PARSE_CREDENTIALS.APP_ID,
'X-Parse-REST-API-Key':PARSE_CREDENTIALS.REST_API_KEY,
'X-Parse-Session-Token': PARSE_CREDENTIALS.PARSE_SESSION
}
});
},
get:function(id){
return $http.get('https://api.parse.com/1/classes/Programme/'+id,{
headers:{
'X-Parse-Application-Id': PARSE_CREDENTIALS.APP_ID,
'X-Parse-REST-API-Key':PARSE_CREDENTIALS.REST_API_KEY,
'X-Parse-Session-Token': PARSE_CREDENTIALS.PARSE_SESSION
}
});
},
create:function(data){
return $http.post('https://api.parse.com/1/classes/Programme',data,{
headers:{
'X-Parse-Application-Id': PARSE_CREDENTIALS.APP_ID,
'X-Parse-REST-API-Key':PARSE_CREDENTIALS.REST_API_KEY,
'X-Parse-Session-Token': PARSE_CREDENTIALS.PARSE_SESSION,
'Content-Type':'application/json'
}
});
},
edit:function(id,data){
return $http.put('https://api.parse.com/1/classes/Programme/'+id,data,{
headers:{
'X-Parse-Application-Id': PARSE_CREDENTIALS.APP_ID,
'X-Parse-REST-API-Key':PARSE_CREDENTIALS.REST_API_KEY,
'X-Parse-Session-Token': PARSE_CREDENTIALS.PARSE_SESSION,
'Content-Type':'application/json'
}
});
},
delete:function(id){
return $http.delete('https://api.parse.com/1/classes/Programme/'+id,{
headers:{
'X-Parse-Application-Id': PARSE_CREDENTIALS.APP_ID,
'X-Parse-REST-API-Key':PARSE_CREDENTIALS.REST_API_KEY,
'X-Parse-Session-Token': PARSE_CREDENTIALS.PARSE_SESSION,
'Content-Type':'application/json'
}
});
}
}
}])
Obviously this x4 is a mess.
So I need to change the URL from /Programmes
to /Users
/Prescription
I am calling this like from my controller like this:
Programme.edit($localStorage.programme.id, {exerciseData:exercises}).success(function(data){
});
Secondly how am I able to tag the error handler onto this controller function as per the Javascript SDK?
Upvotes: 8
Views: 990
Reputation: 33345
I think this really should be done using resources and also abstracting out specific services for you objects not just lumping everything in to one big factory, it is bad habit and form.
Create a separate service for each of your objects... also you should use promises it will lead for better code. Remember a lot of the tutorials that you read/copy from are for the purpose of explaining the technology not building a production application.
Defining a service for a specific object using ng-resource
/**
* this factory wraps the use of angular-resource for interacting with the Kinvey
* models we have created.
* The factory also introduces the use of promises to handle the asynchronous http
* requests.
*
* @see doc - https://docs.angularjs.org/api/ngResource/service/$resource
* @see doc - $q - promises in angular - https://docs.angularjs.org/api/ng/service/$q
*/
.factory('MemberService', ['$resource', 'KINVEY', function ($resource, KINVEY) {
/**
*/
function genericErrorHandler(_error) {
console.log(_error.data);
$scope.response = _error.data;
}
var reqHeaders = {
'Authorization': KINVEY.auth
};
var Member = $resource(KINVEY.baseUrl + "members/:_id", {},
{
// headers are passed in as javascript name/value pairs
'query': {
headers: reqHeaders,
isArray: true
},
'save': {
method: 'POST',
headers: reqHeaders
},
'get': {
headers: reqHeaders
},
'update': {
method: 'PUT',
params: {_id: "@_id"},
headers: reqHeaders
},
'remove': {
method: 'DELETE',
headers: reqHeaders
}
});
return Member;
}]);
Actually using the service
/**
*
* @param $scope
*/
$scope.doList = function () {
// specific helper classes for the HTTP VERBS
MemberService.query()
.$promise.then(function (_response) {
$scope.response = _response;
}).catch(genericErrorHandler);
};
See complete example https://github.com/aaronksaunders/angular-kinvey-dataservices-example
Upvotes: 0
Reputation: 4286
Is this what you mean?
.factory('Programme',['$http','PARSE_CREDENTIALS',function($http,PARSE_CREDENTIALS){
var baseUrl = 'https://api.parse.com/1/classes/';
return {
provider:function(type) {
return {
getAll:function(){
return $http.get(getUrl(type),getParams());
},
get:function(id){
return $http.get(getUrl(type)+id,getParams());
},
create:function(data){
return $http.post(getUrl(type),data,getParams());
},
edit:function(id,data){
return $http.put(getUrl(type)+id,data,getParams());
},
delete:function(id){
return $http.delete(getUrl(type)+id,getParams());
}
}
function getUrl(type) {
return baseUrl+type;
}
function getParams() {
return {
headers:{
'X-Parse-Application-Id': PARSE_CREDENTIALS.APP_ID,
'X-Parse-REST-API-Key':PARSE_CREDENTIALS.REST_API_KEY,
'X-Parse-Session-Token': PARSE_CREDENTIALS.PARSE_SESSION,
'Content-Type':'application/json'
}
}
}
}
}
}])
You can then call it like this:
Programme.provider('Prescription/').edit($localStorage.programme.id, {exerciseData:exercises}).success(function(data){
}).error(function(response){ ... };
Upvotes: 2
Reputation: 1058
1) Use an interceptor to clean up your url code: Put the following in your app.js
$httpProvider.interceptors.push(function ($q) {
return {
request: function(config) {
if (config.url.split('/')[0] === 'api'){
config.url = 'http://yourserverurl:3000/' + config.url.replace('api/', '');
}
return config || $q.when(config);
}
};
});
2) In your url requests, you can now modify them with a simple call to api/class, and you can provide the classname as a parameter to reuse the same function. Example:
create:function(classname, data){
return $http.post('api/' + classname, data, {
headers:{
'X-Parse-Application-Id': PARSE_CREDENTIALS.APP_ID,
'X-Parse-REST-API-Key':PARSE_CREDENTIALS.REST_API_KEY,
'X-Parse-Session-Token': PARSE_CREDENTIALS.PARSE_SESSION,
'Content-Type':'application/json'
}
});
},
3) For error handling on a promise, just use .error( errFunc ) Example:
Programme.edit($localStorage.programme.id, { exerciseData:exercises }).success(function(data){
}).error(function(response){ ... };
p.s For 1 and 2, make sure you add $httpProvider to your .config in app.js
Upvotes: 5