Skip to content

Instantly share code, notes, and snippets.

@ThomasBurleson
Created April 20, 2012 23:36
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ThomasBurleson/2432662 to your computer and use it in GitHub Desktop.
Save ThomasBurleson/2432662 to your computer and use it in GitHub Desktop.
REST services with function currying and promises.
//
// Support API currying...
//
// e.g. var builder = buildCRUDService($rootScope, $http, $log);
//
// API url == http://services.mysite.com/classes/Book/
//
// var Book = builder.serviceFor("Book");
// var book = Book.get(123);
//
function buildCRUDService($rootScope, $http, $log) {
function buildRequestURL(className, objectId) {
var url = "http://services.mysite.com/classes/"+className;
if ( objectId )
url = url + "/" + objectId;
return url;
}
// **********************************************************
// Response Handlers: implemented private function using function currying...
// ************************************************************
var onSuccess = function( callback, logMsg ) {
return function (response) {
$log.log( logMsg || "" );
$rootScope.$apply( function() {
callback(null, response);
});
return response;
};
},
onError = function( callback, defaultErrMsg ) {
return function (response) {
$rootScope.$apply( function() {
callback(response.error || defaultErrMsg );
});
return response;
};
},
// **********************************************************
// CRUD Operations
// ************************************************************
// ::create()
// Create a db object on server
createFn = function( data, callback) {
return $http.post(
buildRequestURL(className),
data,
{ headers: parseHeaders }
)
.then(
onSuccess(callback),
onError(callback,"Cannot submit data!")
);
},
// ::get()
// Get a db object by id
getFn = function(objectId, callback) {
return $http.get(
buildRequestURL(className,objectId),
{ headers: parseHeaders }s
)
.then(
onSuccess(callback),
onError(callback, "Cannot get object "+className+"/"+objectId+"!" )
);
},
// ::query()
// Get a list of db objects with query
queryFn = function( query, callback) {
var config = { headers: parseHeaders };
if (query) config.params = { where: query };
return $http.get(
buildRequestURL(className),
config
)
.then(
onSuccess(callback),
onError(callback, "Could not query "+className+"!" )
);
},
// ::remove()
// Remove a db object
removeFn = function( objectId, callback) {
return $http['delete']( //['delete'] to get around using delete js keyword
buildRequestURL(className,objectId),
{ headers: parseHeaders }
)
.then(
onSuccess(callback),
onError(callback, "Cannot delete object "+className+"/"+objectId+"!" )
);
};
// **********************************************************
// Return CRUD API with curry wrapper
// e.g. var Book = parse.forClass("Book");
// var book = Book.get(123);
// ************************************************************
return {
forClass : function( className ) {
return {
create : createFn,
get : getFn,
query : queryFn,
remove : removeFn
};
}
};
});
@koshuang
Copy link

Hi Thomas,

Thanks for your gist about function currying.

I just wonder if the closure works for the className part, so I try to create a similar jsbin example as following code:

var buildService = function() {

  var create = function() {
    console.log('create a ' + className);
  };

  return {
    forClass: function(className) {
      return {
        create: create
      };
    }
  };
};

service = buildService();
bookService = service.forClass('Book');

bookService.create();

link: http://jsbin.com/camiqukupa/1/edit?html,js,console,output

It shows "className is not defined". Do you know if I am doing something incorrect ?

Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment