Taylorsuk
Taylorsuk

Reputation: 1449

Angular Parse REST factory variables

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

Answers (3)

Aaron Saunders
Aaron Saunders

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

Gabriel Kohen
Gabriel Kohen

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

Olivercodes
Olivercodes

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

Related Questions