Roland
Roland

Reputation: 9701

build API methods as angular service

As I started using AngularJS a couple of days ago, I discovered a lot of useful stuff and I realized that it's easier using it in your web applications rather than building everything from scratch ( sometimes that is necessary but not in most cases ) or using a lot of libraries that may clutter the load time of the app.

So, I had a php API wrapper for an online shop with a lot of methods ( I tried to mimic REST, but the API only offers POST and GET ) and I started building a JS script for it that can be used to call of the methods without any knowledge of PHP or having to touch any PHP code.

Using AngularJS I came up with this :

var Application = Application || {};

;(function($, window, document, undefined) {

"use strict";

var Envato = {};

Application.Envato = angular.module("Envato", []);

Application.Envato.constant("API", {

    Path : {
        Private : "api/envato/private/",
        Public : "api/envato/public/"
    }
});

})(jQuery, window, document);

The above would be my module, placed inside a modules folder. The next, would be the factory build around the module ( placed in the same folder as the above module ) :

var Application = Application || {};

;(function($, window, document, undefined) {

"use strict";

Application.Envato.factory("APIXHRService", function($http, $timeout, $q) {

    return function(method, url, data) {

        var deferred = $q.defer(),
            headers = {
                "Content-Type" : "Application/JSON"
            };

        $http({ method : method, url : url, data : data, headers : headers }).success(function(_data) {

            deferred.resolve(_data);
            deferred = $q.defer();
        }).error(function(_data) {

            deferred.resolve(_data || "Request [ Failed ]");
            deferred = $q.defer();
        });

        return deferred.promise;
    };
});

Application.Envato.factory("Envato", function(APIXHRService, API) {

    return {

        API : {

            Private : {

                User : {

                    Account : function(user){
                        return APIXHRService("POST", API.Path.Private + "get-account-information.php", { user : user });
                    },

                    Statement : function(user) {
                        return APIXHRService("POST", API.Path.Private + "get-statement.php", { user : user });
                    },

                    Sales : function(user) {
                        return APIXHRService("POST", API.Path.Private + "get-recent-sales.php", { user : user });
                    },

                    Transactions : function(user) {
                        return APIXHRService("POST", API.Path.Private + "get-earnings-and-sales-by-month.php", { user : user });
                    },

                    Vitals : function(user) {
                        return APIXHRService("POST", API.Path.Private + "get-user-vitals.php", { user : user });
                    }
                },

                Purchases : {

                    Download : function(user, token) {
                        return APIXHRService("POST", API.Path.Private + "get-item-download-url.php", { user : user, token : token });
                    },

                    Information : function(user, token) {
                        return APIXHRService("POST", API.Path.Private + "get-purchase-information.php", { user : user, token : token });
                    }
                }
            },

            Public : {

                API : {

                    Releases : function() {
                        return APIXHRService("GET", API.Path.Public + "get-api-releases.php");
                    }
                },

                Blog : {

                    Posts : function(marketplaces) {
                        return APIXHRService("POST", API.Path.Public + "get-blog-posts.php", { marketplaces : marketplaces });
                    },

                    Threads : {

                        Active : function(marketplaces) {
                            return APIXHRService("POST", API.Path.Public + "get-active-threads.php", { marketplaces : marketplaces });
                        },

                        Status : function(threads) {
                            return APIXHRService("POST", API.Path.Public + "get-thread-status.php", { threads : threads });
                        }
                    }
                },

                Collections : function(collections) {
                    return APIXHRService("POST", API.Path.Public + "get-collections.php", { collections : collections });
                },

                Items : {

                    Count : function(marketplaces) {
                        return APIXHRService("POST", API.Path.Public + "get-items-count.php", { marketplaces : marketplaces });
                    },

                    Featured : function(marketplaces) {
                        return APIXHRService("POST", API.Path.Public + "get-featured-items.php", { marketplaces : marketplaces });
                    },

                    Information : function(items) {
                        return APIXHRService("POST", API.Path.Public + "get-item-information.php", { items : items });
                    },

                    Latest : {

                        Marketplace : function(marketplaces) {
                            return APIXHRService("POST", API.Path.Public + "get-new-items-from-market.php", { marketplaces : marketplaces });
                        },

                        Random : function(marketplaces) {
                            return APIXHRService("POST", API.Path.Public + "get-random-new-items.php", { marketplaces : marketplaces });
                        },

                        User : function(users) {
                            return APIXHRService("POST", API.Path.Public + "get-new-items-from-user.php", { users : users });
                        }
                    },

                    Popular : function(marketplaces) {
                        return APIXHRService("POST", API.Path.Public + "get-popular-items.php", { marketplaces : marketplaces });
                    },

                    Price : function(items) {
                        return APIXHRService("POST", API.Path.Public + "get-item-price.php", { items : items });
                    }
                },

                Users : {

                    Information : function(users) {
                        return APIXHRService("POST", API.Path.Public + "get-user-information.php", { users : users });
                    },

                    Items : {

                        Count : function(users) {
                            return APIXHRService("POST", API.Path.Public + "get-user-items-by-site.php", { users : users });
                        }
                    },

                    Total : function() {
                        return APIXHRService("GET", API.Path.Public + "get-total-users-count.php");
                    },
                },

                Search : function(expression, marketplace, categories) {
                    return APIXHRService("POST", API.Path.Public + "get-search-results.php", { expression : expression, marketplace : ( marketplace === undefined ? "" : marketplace ), categories : ( categories === undefined ? "" : categories ) });
                }
            }
        }
    };
});

})(jQuery, window, document);

And lastly, if needed, I had a controller that allows me to check if the methods work properly :

var Application = Application || {};

;(function($, window, document, undefined) {

"use strict";

Application.controller("EnvatoAPIController", ["$scope", "_debounce", "Envato", function($scope, _debounce, Envato) {

    $scope.getData = _debounce(function($event) {

        $event.preventDefault();

        return Envato.API.Private.Purchases.Download("chaoscod3r", "52dfdscb1-dada-4ff8-bfcb-d3fdsbn55mda").then(function(data) {
            $scope.data = JSON.stringify(data, undefined, 4);
        });

    }, 250, false);

}]);

})(jQuery, window, document);

The reason why I'm posting this is that I'm looking for some insights on how I could improve my code, as it seems to me that it's a bit to much going on in there. Maybe there's a better way of doing it with Angular ? I haven't got the chance to get through all the AngularJS API docs, so I guess there must be a lot of developers here that are using Angular and could give me some tips :)

EDIT : The question is how can I refractor the Envato factory ? Which way would be the best ?

Upvotes: 0

Views: 1082

Answers (1)

Gregor
Gregor

Reputation: 756

You can save some lines if you omit the global app var declaration and attach all angular modules to the angular object. (I am not sure where to put the "use strict"; statement though.)

Also use the bracket notation for the dependency injection to enable js code minification later on.

before:

var Application = Application || {};

;(function($, window, document, undefined) {

    Application.Envato.factory("APIXHRService", function($http, $timeout, $q) {
       return function (
       //something
    });

    Application.Envato.factory("Envato", function(APIXHRService, API) {
        return {
            //api
        };
    });

})(jQuery, window, document);

after:

angular.factory("APIXHRService", ["$http", "$timeout", "$q", function($http, $timeout, $q) {
   return function (
   //something
}])

.factory("Envato", ["APIXHRService", "API", function(APIXHRService, API) {
    return {
        //api
    };
}]);

Upvotes: 1

Related Questions