What happens when the resolve fails in UI router and the view doesn't load?

It seems like I may be missing something, but when I set a state like this:

.state('session_register', {
        url: '/privatearea',
        resolve: {
            isLogged: function(Session){
                return Session.isLogged();
            } 
        },
        templateUrl: 'private/user.html',
        controller:'UserController'
 })

If the isLogged function returns a 401 status (resolve fails), even though I don't see the user.html in the browser, the partial is still loaded according to Firebug.

This brings up the question:

Is this the intended behavior?

Is there a way to prevent loading the partial when a resolve fails?

I also have an httpInterceptor setup:

.factory('httpInterceptor', ['$q', '$location',
    function($q, $location) {
      return {
        'response': function(response) {
          if (response.status === 401) {
            $location.path('/auth/login');
            return $q.reject(response);
          }
          return response || $q.when(response);
        },

        'responseError': function(rejection) {

          if (rejection.status === 401) {
            $location.url('/auth/login');
            return $q.reject(rejection);
          }
          return $q.reject(rejection);
        }

      };
    }
  ])
//Http Interceptor to check auth failures for XHR requests
.config(['$httpProvider',
  function($httpProvider) {
    $httpProvider.interceptors.push('httpInterceptor');
  }
]);

END UP

.factory('httpInterceptor', ['$q','$location',function ($q,$location) {
        var canceller = $q.defer();
        return {
            'request': function(config) {
                // promise that should abort the request when resolved.
                config.timeout = canceller.promise;
                return config;
            },
            'response': function(response) {
                return response;
            },
            'responseError': function(rejection) {
                if (rejection.status === 401) {
                    canceller.resolve('Unauthorized'); 
                    $location.url('/user/signin');
                    return $q.reject(rejection);
                }
                if (rejection.status === 403) {
                    canceller.resolve('Forbidden');  
                    $location.url('/');
                    return $q.reject(rejection);
                }
                return $q.reject(rejection);
            }

        };
    }
    ])
    //Http Intercpetor to check auth failures for xhr requests
   .config(['$httpProvider',function($httpProvider) {
        $httpProvider.interceptors.push('httpInterceptor');
    }]);

And it works perfectly :)

Answer №1

It seems to be intentional design. Blocking template loading would only slow down the view completion without any additional benefit in terms of bandwidth.

The behavior cannot be changed, as indicated in the source code:

https://github.com/angular-ui/ui-router/blob/0.2.10/src/state.js#L1158

dst.resolve = $resolve.resolve(state.resolve, locals, dst.resolve, state);
var promises = [ dst.resolve.then(function (globals) {
  dst.globals = globals;
}) ];
if (inherited) promises.push(inherited);

// Resolve template and dependencies for all views.
forEach(state.views, function (view, name) {
  var injectables = (view.resolve && view.resolve !== state.resolve ? view.resolve : {});
  injectables.$template = [ function () {
    return $view.load(name, { view: view, locals: locals, params: $stateParams, notify: false }) || '';
  }];

  promises.push($resolve.resolve(injectables, locals, dst.resolve, state).then(function (result) {
    // References to the controller (only instantiated at link time)
    if (isFunction(view.controllerProvider) || isArray(view.controllerProvider)) {
      var injectLocals = angular.extend({}, injectables, locals);
      result.$$controller = $injector.invoke(view.controllerProvider, null, injectLocals);
    } else {
      result.$$controller = view.controller;
    }
    // Provide access to the state itself for internal use
    result.$$state = state;
    result.$$controllerAs = view.controllerAs;
    dst[name] = result;
  }));
});

// Wait for all the promises and then return the activation object
return $q.all(promises).then(function (values) {
  return dst;
});

A promise from state.resolve:

$resolve.resolve(state.resolve, locals, dst.resolve, state);

and $view.load (which initiates an http request for the templateUrl):

$view.load(name, { view: view, locals: locals, params: $stateParams, notify: false })

do not wait for each other to finish first, they run in parallel and are used in the return statement:

return $q.all(promises).then(function (values) {

I hope this explanation clarifies things.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

When a block reaches a certain height, the mat-chip-list in Angular Material is automatically shortened to fit. This feature is exclusive to

<div fxFlex="100" fxFlex.gt-sm="80" fxFlex.sm="100"> <div *ngFor="let permission of arrayOfObjectPermissions; let index = z" class="permissions-list"> <mat-card [title]=&qu ...

Executing certain test suites with defined capabilities in Protractor

My website is designed to be compatible with both desktop and mobile browsers, each having its own unique user interface. In my protractor config file, I have some suites that need to be tested using the desktop user agent, while others require testing usi ...

How to Install Definitely Typed Packages in Visual Studio 2015 RC for AspNet5 with the Help of Gulp and TSD

Struggling to add angular.d.ts to my MVC6 project, I've hit a roadblock. Although I've configured Gulp to reinstall necessary packages using tsd, I'm stuck on the initial installation process. The instructions suggest running 'tsd inst ...

"Troubleshooting null values in an Angular form submission handled by a C# MVC

Having issues sending data from AngularJS to a C# MVC controller. Even though the data is collected properly (confirmed by viewing them with console.log), they are not being received correctly in the C# controller, resulting in null values being stored in ...

Updating data in AngularJS after inserting a new record

What is the most efficient method to update comments data when a new record is added to the database? I currently have this code that works well, but I am concerned that it may be slow if there are a large number of comments. Any assistance would be greatl ...

"Step-by-step guide on populating a select box with data from the scope

Hey everyone, I'm new to using Angular and hoping for some help with a simple question. I've created a form (simplified version below) that I want users to see a live preview as they fill it out. Everything was going smoothly with regular field ...

Encountering a running error in a Strongloop tutorial

I have been reviewing the Strongloop documentation and decided to try out the tutorial on how to Add a client app. I followed all the steps provided and was able to successfully run the app using slc run without encountering any errors. However, upon check ...

Troubleshoot: Why is my AngularJS bootstrap.ui modal failing to

I am experiencing an issue with displaying a modal dialog using AngularJS bootstrap.ui. After calling $modal.open(...), the screen grays out, the HTML from my templateUrl is fetched from the server, but the modal does not appear. When I click on the gray a ...

Guide to retrieving and showing specific items from a DropDownList in a Text box using JavaScript, HTML, and AngularJS

Can someone explain how to extract and select items from a DropDownList and display them in a Textbox using JavaScript/HTML/AngularJS? Here are more details: I have a dropdown list with many items. When I click on an item from the list, it should be dis ...

When employing UI-Router, custom directives may not function properly within nested views

I was developing an angular application using phonegap, ionic, and angular. I had created a custom directive that registered an event listener for the element to activate iScroll upon loading. Initially, the directive worked perfectly when all the views we ...

What is the best way to transfer a base64 image string obtained from pouchdb to a different api as a file?

I have stored an image in base64 format within pouchdb, and I am now looking to upload the same file to a specific API on the server. Is there a way for me to extract the file path or convert the base64 image back into a regular file so that it can be acc ...

Issue with Angular JS: ng-repeat not refreshing within ng-view

Whenever I make changes to the data stored in the variable $scope.userMovies, ng-repeat fails to update when it is inside an ng-view. Strangely enough, if it's placed outside of ng-view, everything updates as intended. What could be the reason behind ...

Angular's Restangular initiates a blank promise at the beginning

One of the services I created can fetch data from the server and cache it, or retrieve data directly from the cache. The code snippet below illustrates this functionality. While using .then statements in the client side for cached data, I've noticed ...

Unexpected Memory Drain in Ionic and Cordova on iOS

I've encountered an unusual memory leak in my Ionic and Cordova application. This leak is not present when running the app in Chrome, but it clearly appears when I test the app. The issue arises when I need to iterate through a large data set and assi ...

Trouble initializing Google Maps in an Angular directive

I'm currently working on integrating the Google Maps API into an Angular website, but I'm encountering initialization issues. Within my HTML page, I'm utilizing bootstrap nav nav-tabs and switching between tabs using an Angular controller. ...

Utilizing ng-click and ng-switch during the submission of an Angular form

I am working on a single-page Angular app where the landing page is a sign-in form with a link to a sign-up form. The rest of the app remains hidden until the user has been authenticated. To switch between the sign-in and sign-up pages, I am using the ng ...

Custom AngularJS menu directive using a JSON file to generate submenus

As a newcomer to angularJs, I am looking to create a dynamic menu with submenus using a .json file. It's important for me to be able to easily add new menus and submenus through the same .json document. <a href="#" ng-repeat="item in menuHeader"&g ...

Sort objects based on a specific property that they possess

In my current setup, I have an array of objects structured as shown below: $scope.people = [{name: {last:"Doe", first:"John"}}, {name: {last:"Smith", first:"Joe"}}]; My goal is to implement a live filt ...

"Attempting to connect to REST server using angularjs $resource. Unexpectedly, the success callback does not

After attempting to set up a REST server on Nodejs and accessing it from AngularJS using $resource for the first time, I have encountered some issues... In my controller, I am trying to load a JSON object (shopping cart) upon login for existing users or c ...

Is it possible to move a directive within a limited parent element?

Is there a way to limit the movement of an angular.js drag directive within the confines of its parent element? You can see the problem I'm facing in this jsbin: http://jsbin.com/maxife/3/edit?html,css,js,output ...