ng-grid won't load header row template when using $http interceptors to modify request url

StackOverflow https://stackoverflow.com/questions/21121085

  •  28-09-2022
  •  | 
  •  

Question

Our application uses an $http interceptor to add tokens to $http requests as a form of security, the token that the interceptor adds are updated every 5 or so minutes. We now want to use ng-grid.

However, the $http interceptor makes is so that ng-grid will not load the template it uses for the header row, which causes the header row to not render.

Here is the issue in action: http://plnkr.co/edit/krvBF2e4bHauQmHoa05T?p=preview

If you check the console it shows the following error:

GET http://run.plnkr.co/l0BZkZ2qCLnzBRKa/ng1389719736618headerRowTemplate.html?securityToken=123456 404 (Not Found)

The reason why this happens is because ng-grid stores the template for the header row in the $templateCache, and then uses an ng-include to later retrieve it.

ng-include uses a $http.get request, with $templateCache as the cache, to get the template.

The $http.get request is intercepted by the interceptor which adds the security token to the url before it has a chance to query $templateCache for the template using the url.

$templateCache is expecting ng1389719736618headerRowTemplate.html but instead gets ng1389719736618headerRowTemplate.html?securityToken=123456

The result is that the $templateCache can't find the template, which then results in $http.get hitting the server and getting the 404 error.

The other issue is that if we ever wanted to use $templateCache to store templates and later retrieve it with ng-include or $http.get, $templateCache would not being able to find the template because the url would get modified.

How can I get ng-grid to display the header row with the $http interceptor adding security tokens to the end of the urls?

here is the code Html:

<!DOCTYPE html>
<html ng-app="myApp">
    <head lang="en">
        <meta charset="utf-8">
        <title>Custom Plunker</title>  
        <link rel="stylesheet" type="text/css" href="http://angular-ui.github.com/ng-grid/css/ng-grid.css" />
        <link rel="stylesheet" type="text/css" href="style.css" />
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.min.js"></script>
        <script type="text/javascript" src="http://angular-ui.github.com/ng-grid/lib/ng-grid.debug.js"></script>
        <script type="text/javascript" src="main.js"></script>
    </head>
    <body ng-controller="MyCtrl">
        <div class="gridStyle" ng-grid="gridOptions"></div>
    </body>
</html>

javascript:

var app = angular.module('myApp', ['ngGrid']);
app.controller('MyCtrl', function($scope) {
    $scope.myData = [{name: "Moroni", age: 50},
                 {name: "Tiancum", age: 43},
                 {name: "Jacob", age: 27},
                 {name: "Nephi", age: 29},
                 {name: "Enos", age: 34}];
    $scope.gridOptions = { data: 'myData' };
});

app.config(function($provide, $httpProvider) {
    $provide.factory('tokenAuthInterceptor', function($q){
        return {
            // optional method
            'request': function(config) {
                // do something on success
                config.url = config.url + "?securityToken=123456";
                return config || $q.when(config);
            }
        };
    });
    $httpProvider.interceptors.push('tokenAuthInterceptor');
});

Update

The solution that was finally decided upon was to use an angular decorator and decorate $templateCache, the plunker was updated to reflect this.

$provide.decorator('$templateCache', function($delegate) {
    var get = $delegate.get;
    function formatKey(key)
        {
         // code for formatting keys
        }
        $delegate.get = function(key) {
            var entry = get(key);
            if (entry)
            {
                return entry;
            }
            else
            {
                return get(formatKey(key));
            }
        };
    return $delegate;
});

No correct solution

OTHER TIPS

We ran into this same issue and implemented a quick check in our interceptor to check if the item was already in the templateCache.

if ($templateCache.get(config.url)){
    return config;
}

I got the idea from the cachebuster project.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top