Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular ui-router seems to re-write url automatically on load

Changing routes via ui-sref works correctly.

When I refresh the page manually on the base url (example.com/account), everything similarly works.

However, when I refresh the page manually and the url contains a hashbang (i.e. http://example.com/account/#/billing, I see the following error in the console.

TypeError: Cannot read property 'charAt' of undefined
at Object.$$parse (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular.js:9321:40)
at https://ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular.js:9878:21
at Scope.$get.Scope.$eval (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular.js:12701:28)
at Scope.$get.Scope.$digest (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular.js:12513:31)
at Scope.$get.Scope.$apply (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular.js:12805:24)
at done (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular.js:8378:45)
at completeRequest (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular.js:8592:7)
at XMLHttpRequest.xhr.onreadystatechange (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular.js:8531:11)

After reading about this error and adding breakpoints, I noticed that, on load, the path is being temporarily rewritten from forms like

/account/#/billing
/account/#settings

where account is the base for the app, to forms like

/billing/ 
/settings/

Eventually, after the error occurs, the correct url forms are restored in the address bar.

These temporary (intermediate) paths seem to cause the following code in $$parse to break. AppBase is bound to "example.com/account/" and url is bound to values like "mysite.com/billing". withoutBaseUrl is bound to undefined since the url does not contain characters extending beyond appBase.

  this.$$parse = function(url) {
    var withoutBaseUrl = beginsWith(appBase, url) || beginsWith(appBaseNoFile, url);
    var withoutHashUrl = withoutBaseUrl.charAt(0) == '#'
        ? beginsWith(hashPrefix, withoutBaseUrl)
        : (this.$$html5)
          ? withoutBaseUrl
          : '';

Here is my relevant code:

 plaidApp.config(['$stateProvider', '$urlRouterProvider',
'$interpolateProvider', function($stateProvider,
  $urlRouterProvider, $interpolateProvider) {

$stateProvider
  .state('account', {
    url: '/',
    controller: 'MainCtrl',
    templateUrl: 'dashboard_home.html',
  });

$stateProvider
  .state('metrics', {
    url: '/metrics',
    controller: 'MetricsCtrl',
    templateUrl: 'dashboard_metrics.html',
    resolve: {
      actions: ['actionModel', function(actionModel) {
        return actionModel.fetch();
      }]
    }
  });

$stateProvider
  .state('billing', {
    url: '/billing',
    controller: 'BillsCtrl',
    templateUrl: 'dashboard_billing.html',
    resolve: {
      bills: ['billingModel', function(billingModel) {
        return billingModel.fetch();
      }]
    }
  });

$stateProvider
  .state('resources', {
    url: '/resources',
    controller: 'MainCtrl',
    templateUrl: 'dashboard_resources.html',
  });

$stateProvider
  .state('settings', {
    url: '/settings',
    controller: 'SettingsCtrl',
    templateUrl: 'dashboard_settings.html',
  });

$urlRouterProvider.otherwise('/#');
$interpolateProvider.startSymbol('{[{').endSymbol('}]}');

}]);

like image 757
Ben Avatar asked Oct 31 '22 12:10

Ben


1 Answers

Try writing the interpolate statement before the routes are defined:

$interpolateProvider.startSymbol('{[{').endSymbol('}]}');

$stateProvider
 .state('account', {
 ...

The template linking and compiling might have started before the interpolate statement is executed and in that template if you have used '{[}', it might not be able to parse it.

like image 155
yeswanth Avatar answered Nov 11 '22 03:11

yeswanth