Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reuse Services without circular dependencies

Tags:

I have one service that is globally storing all my data used through out my app.

GlobalDataService (GDS)

angular
        .module('app.core')
        .service('GlobalDataService', GlobalDataService);
    GlobalDataService.$inject = ['$http', 'LineStatusService'];
    function GlobalDataService($http, LineStatusService) {
        var gds = this;

        gds.data = {
            //all my data
        }

        gds.data.lines = LineStatusService.getLineStatus().then...
    }

And a simple crud service that handles the Status of my data.

StatusDataService (SDS)

angular
        .module('app.core')
        .service('LineStatusService', LineStatusService);
    LineStatusService.$inject = ['$http', 'GlobalDataService'];
    function LineStatusService($http, GlobalDataService) {
        var service = {
            getLineStatus: getLineStatus,
            saveLineStatus: saveLineStatus,
            ...
        };

        function saveLineStatus (line, status, user) {
            var data = {
                status: {
                    status_id: status.status_id,
                    status_desc: status.status_desc
                },
                updated_by: user
            }

            return $http.post('/api/euauto/v1/delivery-status/linestatus', data)
            .then(function successCallback(response) {
                GlobalDataService.data[id].status = status;
                return response.data;
            }).catch(function errorCallback(response) {

            });
        }

        return service;
    }

The GDS has to request all Status's when the app first loads, then the Status Service handles any other data requests.

Now I understand you can't have circular dependencies, therefore my plan was to have my Controller handle the save and update using SDS and ALSO update the GDS.

Potential Solution

angular
        .module('core')
        .controller('MyController', MyController);

    MyController.$inject = ['GlobalDataService', 'LineStatusService'];
    function MyController(GlobalDataService, LineStatusService) {
        function changeStatus(line, status, user) {
            //do a thing
            //and another
            LineStatusService.saveLineStatus(line, status, user);
            GlobalDataService.data.line[id] = status;
            GlobalDataService.updateAllOtherData();
            //etc...
        }
    }

The Problem

My question is, now I want to develop a new Controller which contains the exact same functionality I will now have to remember to copy the same code and business logic from my original Controller to reuse both Services. Also, if the GDS doesn't depend on SDS it won't be able to getLineStatus() on load and each Controller in the app will have to remember to getLineStatus() on load.

Ideally all the logic and requests should be contained in one place, preferably my SDS. My GDS data should be consistent across the whole Application.

like image 747
Nick Avatar asked Sep 06 '17 16:09

Nick


1 Answers

If GlobalDataService is supposed to be initialized with data when the app starts, then you could initialize it in a .run() block instead of in the service constructor. That way the GDS does not need to have the other services injected at all. The other data services can then have GDS injected without circular dependency issues.

angular
    .module('app.core')
    .run(function(GlobalDataService, LineStatusService) {

    GlobalDataService.data.lines = LineStatusService.getLineStatus().then...

});
like image 69
JC Ford Avatar answered Oct 04 '22 21:10

JC Ford