Search code examples
javascriptangularjsangularjs-serviceangularjs-factory

How do I convert a controller http call to a Service/factory pattern that takes in a parameter


I have a controller that is calling http.get, http.push and http.post methods.

I am learning angularjs and have found that it's best to call your http.get in your service file. I am able to do that with a simple http.get, but get confused with a http.get by id or http.get/http.post which takes a parameter:

My current controller looks like this

angular.module("app-complaints")
.controller("clcontrol", clcontrol);

function clcontrol($routeParams, $http, $scope) {
 $http.get(baseURL + "/api/complaints/" + $scope.complaintCase + "/checklists")
    .then(function (cl) {
        //success
        $scope.index = 0;
        $scope.cl = [];
        $scope.cl = cl;
}

I want to separate it out like this

controller.js

angular.module("app-complaints")
.controller('clcontrol', function ($http, $scope, $q, Service, $timeout) {
....
getCL();
function getCL(){
Service.getCl()
.success(function(cl){
$scope.cl = [];
$scope.cl = cl;
}

service.js

angular.module("app-complaints")
.factory('Service', ['$http', function ($http) {
        Service.getCL = function () {
        return $http.get(urlBase + "/api/complaints/" + complaintCase + "/checklists")
    };

 };

Solution

  • Simple. Make a factory that accepts parameters.

    var app = angular.module("MyApp", [ /* dependencies */]);
    
    app.factory("SharedServices", ["$http", function($http) {
        return {
            getItems: function(url, parameters) {
                return $http.get(url, {
                    //optional query string like {userId: user.id} -> ?userId=value
                    params: parameters
                });
            },
            postItem: function(url, item) {
                var payload = {
                    item: item
                };
                return $http.post(url, payload);
            },
            deleteItem: function(url, item) {
                var payload = {
                    item: item
                };
                return $http({
                    url: url,
                    data: payload,
                    method: 'DELETE',
                });
            }
            // ETC. ETC. ETC.
            // follow this pattern for methods like PUT, POST, anything you need
        };
    }]);
    

    Use the service in your controller:

    app.controller("MainCtrl", ["$scope","SharedServices", function($scope, SharedServices) {
    
        //do things with the shared service
        $scope.postMyThings = function() {
            SharedServices.postItems('path/to/api', itemsArray).then(function(response) {
                //success callback, do something with response.data
            }, function(response) {
                //an error has occurred
            });
        };
    
        $scope.getMyThing = function() {
            SharedServices.getItems('path/to/api/get').then(function(response) {
                //success callback, do something with response.data
            }, function(response) {
                //an error has occurred
            });
        }
    
    }]);