Harvey Mushman
Harvey Mushman

Reputation: 670

Data Store using $resource, $cacheFactory with errorHandlingDirective

Learning AngularJS and trying to create a SPA with a data store for a REST server. To reduce the traffic as much as possible, I want to cache the data whenever possible. In the case of an error response from the server, I would like to handle in one common directive for all callbacks. This would allow me to the directive across several controllers in a common way.

This post all works except the $emit and/or $broadcast are not firing off the event that the directive is waiting $on. If it was working the template in the Directive will have the error description and be displayed on the HTML page when isError becomes true. At least that is my present thinking...

Plunker

My sample HTML file:

<!DOCTYPE html>
<html ng-app="app">

<head>
<script data-require="[email protected]" src="https://code.angularjs.org/1.2.16/angular.js" data-semver="1.2.16">    </script>
<script data-require="[email protected]" data-semver="1.2.14" src="http://code.angularjs.org/1.2.14/angular-resource.js"></script>
<!--script src="app.js"></!--script-->
</head>
<body ng-controller="MainCtrl">
<h1>Hello Plunker!</h1>
{{data}}
<br />
<br />
isError: <error></error>

<br /><br />
Cached Data: {{dataCache}}

<br /><br />
<button ng-click="getData()">Data Callback</button>
<br /><br /><br />
<button ng-click="getError()">Callback Error</button>
<br /><br /><br />
Cache Info: {{oDataServiceInfo}}<br />
<button ng-click="resetCache()">Reset Cache</button>

</body>
</html>

My sample Controller:

var app = angular.module('app', ['ngResource']);

app.controller('MainCtrl', ['$scope', '$rootScope', 'loDataService', function ($scope,$rootScope, loDataService) {

    $scope.getData = function () {
        loDataService.getData(function (data) {
            $scope.dataCache = loDataService.lCache
            $scope.oDataServiceInfo = loDataService.oInfo;
            $scope.data = data;
        }, function (error) {
            console.log(error);
        })
    };

    $scope.getError = function () {
        loDataService.getError(function (data) {
            $scope.dataCache = loDataService.lCache
            $scope.oDataServiceInfo = loDataService.oInfo;
            $scope.data = data;
        }, function (error) {
            $rootScope.$broadcast("resourceError", error);

            console.log(error);
        })

    };

    $scope.resetCache = function () {
        loDataService.resetCache();
        $scope.oDataServiceInfo = loDataService.oInfo;
    };


}]);

My sample data store:

app.factory('loDataService', ['$resource','$cacheFactory','$rootScope', function ($resource, $cacheFactory, $rootScope) {
    var dbcCache = $cacheFactory('loDataService');
    var oDBC = $resource('/', {},
        {
            'GetError': { url:'nonExistingConnection',method: 'GET' },
            'GetData': { url: 'sampleData.json', method: 'GET', isArray: false }
        });

    return {
        lCache: true,
        oInfo: {},
        resetCache: function () {
            dbcCache.removeAll();
            this.oInfo = dbcCache.info();
        },
        getData: function (callback, callbackError) {
            _this = this;
            var markets = dbcCache.get('Markets');
            if (!markets) {
                // fetch from server
                _this.lCache = false;
                oDBC.GetData(function (response) {
                    // store in cache
                    dbcCache.put('Markets', response.Markets);
                    _this.oInfo = dbcCache.info();
                    // return response
                    callback(response.Markets);
                },
                    function (error) {
                        // oh no, what went wrong?
                        callbackError(error);
                    });
            } else {
                // return the cache
                _this.lCache = true;
                callback(markets);
            }
        },
        getError: function (callback, callbackError) {
            _this = this;
            var marketsX = dbcCache.get('MarketsX');
            if (!marketsX) {
                // fetch from server
                _this.lCache = false;
                oDBC.GetError(function (response) {
                    // store in cache
                    dbcCache.put('MarketsX', response.Markets);
                    // return response
                    callback(response.Markets);
                },
                    function (error) {
                        // oh no, what went wrong?
                        callbackError(error);
                        $rootScope.$broadcast("resourceError", error);
                    });
            } else {
                // return the cache
                _this.lCache = true;
                callback(marketsX);
            }
        }
    }

}]);

My sample Directive:

app.directive("resourceError", ['$rootScope', function ($rootScope) {
    return {
        restrict: 'E',
        template: '<div class="alert-box alert" ng-show="isError" >Error!!!</div>',
        link: function (scope) {
            $rootScope.$on("resourceError", function (event, error) {
                scope.isError = true;
                console.log(error);
            })
        }
    }
}]);

Here in my "sampleData.json" file.

{
    "Markets": [{
        "id": 1,
        "name": "Downtown",
        "eventday": "1/1/1991",
        "active": true
    }, {
        "id": 2,
        "name": "County",
        "eventday": "2/2/1991",
        "active": true
    }, {
        "id": 3,
        "name": "Beach",
        "eventday": "3/3/1991",
        "active": false
    }]
}

Any thoughts?

Upvotes: 2

Views: 250

Answers (0)

Related Questions