ThomasBurleson
4/20/2012 - 11:36 PM

REST services with function currying and promises.

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
			};
		}
	};

});