Using Angular route resolve to handle the sessionStorage login status

I have successfully created a login system using Angular JS. Once the user logs in, a session storage variable is set and they are redirected to a dashboard page (which should only be accessible when logged in).

$window.sessionStorage["isLoggedIn"] = true;
$location.path("/dashboard"); 

Now I am looking to implement resolve on routes that require the user to be logged in. However, I am finding the documentation confusing and difficult to understand. If a user who is not logged in tries to access one of these protected pages, they should be prompted with a message indicating they cannot access that page.

app.config(function($routeProvider) {
  $routeProvider.when("/dashboard", {
    templateUrl : "framework/views/dashboard.html",
    controller  : "DashboardCtrl",
    title: "Dashboard",
    resolve: {
      //how does this work?!
    }
});


app.factory("loginCheckService", function(){
  //check sessionStorage and return?
});

Answer №1

It is recommended to listen for the locationChangeStart event, conduct necessary validations (such as authorization), halt the route change if needed, and trigger certain events (like showing the login form in case of unauthorized access).

An example implementation:

app.run(function($rootScope, AuthenticationService){
      $rootScope.$on('$locationChangeStart', function(event){
          if(!AuthenticationService.isUserLoggedIn()){
            event.preventDefault();
             //AuthenticationService.raiseUserNotLoggedIn();  OR
                 $rootScope.$broadcast('UserNotLoggedIn');
         }

      });
  });

app.controller('LoginFormController',function($scope){
    $scope.userLoggedIn=true;
    $scope.on('UserNotLoggedIn', function(){
          $scope.userLoggedIn=false;
    });
});

Answer №2

Resolve enables you to specify a series of tasks that must be completed before the route is loaded. It consists of keys and functions, allowing you to perform actions like asynchronous http requests, executing code snippets, setting values, and more before the page loads.

For example, if you have a service that makes an http get request and returns a promise to ensure a session exists on the server every time a route is accessed, resolve ensures that the page will not load until the http request is successful and the promise is fulfilled. If the promise fails to fulfill, the page will not load:

.config([ '$routeProvider', function( $routeProvide ) {

    $routeProvider.when('/dashboard', {
        templateUrl: 'framework/views/dashboard.html',
        controller: 'DashboardCtrl',
        controllerAs: 'dashCtrl',
        resolve: {
            DateOfBirth: ['Date', function( Date ) {  // another example of using resolve
                return Date.getCurrentYear() - 37;
            }],
            AuthUser: ['$q', '$location', 'UserSession', 

                function( $q, $location, UserSession) {
                    return UserSession.getSession()

                    .then(function( success ) {  
                        // execute actions when promise is successful

                        // handle logic here

                       return success
                    }, function( error ) { 
                        // execute actions when promise fails

                       // handle logic here                         

                       $location.path('/login);
                       $location.replace();

                       return $q.reject( error );
                    });
        }];
        }
    })
}]);

One advantage of resolve is that the keys are injectable, allowing you to pass the result to your controller:

.controller('DashboardCtrl', ['AuthUser', 'UserSession', 'DateOfBirth' 
    function(AuthUser, UserSession, DateOfBirth) {

    var self = this;

    self.status = AuthUser.status;
    self.response = AuthUser.data;
}]);

You can then use the resolved data in your UI, displaying errors using dashCtrl.response or dashCtrl.status, knowing that the page has not loaded yet.

I recommend checking the session upon route access instead of storing it on the client side. Additionally, keep in mind that resolve only works with routes. For server calls unrelated to routing, consider using interceptors to monitor outgoing and incoming requests/responses while on specific pages like /dashboard/home without triggering a route change.

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

Error: Controller not found when angular.module is called from different files

As I am restructuring my code to make it more modular, I decided to move the controller into a separate file that belongs to the same module. However, I am facing an issue where the controller does not load, even though I have verified that the load order ...

JavaScript Button with the Ability to Input Text in a TextArea?

For instance, imagine a scenario where you click on a button and it then displays various options for you to select from. Whatever option you pick will be automatically inserted into the text area. ...

What is the best approach for loading locally stored images conditionally in Vue.js?

<template> <div> <div v-if="item"> <h1>Price: {{ item.email }}</h1> <v-if item.email=="<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="670d080f0927000a060e0b4904080a">[email& ...

Angular Fire: The $on method is missing and causing an error stating that undefined is not a function

I am currently attempting to log my Firebase data to the console, but I keep encountering an error stating undefined is not a function. Below is the full error message: TypeError: undefined is not a function at Object.childAdded (http://localhost:9000/scr ...

Conceal overflow in SVG after stroke is applied to top rectangle border

Is there a way to conceal the overflowing red color in this SVG? I attempted repositioning it before the rect with the stroke, but that didn't solve the issue. Check out the code and screenshot below. <br><br> <svg _ngcontent-fdl-c1 ...

Trouble arises with Webpack during the compilation of JavaScript files

I've been tackling a project in Laravel 5.3, smoothly using webpack until I decided to configure ES6 by adding babel packages to my npm module. This caused a code breakdown, prompting me to revert back to the initial setup. However, now every time I m ...

Swipe to modify Array

Currently, I am in the process of developing an application that features a Swipe card interface using both AngularJS and the Ionic framework. The functionality of this app will be similar to the one found at . When swiping to accept a card, I want the ar ...

Showing VUE Content Delivery Network

Unable to render v-for with CDN in Vue.js const Gallery = { template: '{{$t('gallery')}} <img :class="[[item.class]]" v-for="(item, index) in carousel" :src="[[item.img]]" alt="img" />' } c ...

Coming back from retrieving data from an API

I'm having trouble with a function that performs a POST request to retrieve access tokens from an API. Although the function successfully prints the token to the console, I haven't been able to figure out how to properly parse and save the access ...

When using Mongoose paginate, there is always one missing document

I currently have a database with 6 documents and the following route: router.get('', async (req, res) => { const search = req.query.search !=null ? req.query.search : ""; const page = req.query.page !=null ? req.query.page : 1; const limit = ...

Enhancing the efficiency of a Puppeteer web scraping operation

app.get("/home", async (req, res) => { try { const browser = await puppeteer.launch(); const page = await browser.newPage(); const pageNumber = req.query.page || 1; await page.goto(`https://gogoanimehd.io/?page=${pageNumber ...

Issue with JQuery dialog not triggering autocomplete

I have integrated the JQuery 1.7.2 and JQuery-UI 1.8.18 libraries with both http://docs.jquery.com/UI/Dialog and http://docs.jquery.com/UI/Autocomplete. On a standard page load, the autocomplete function works perfectly with a text box in a form. It' ...

Can you display names in capital letters from the randomUser.me API?

Apologies if this is not the appropriate platform for my query. Just to provide context, I am a designer with minimal experience in APIs and Javascript. I am currently utilizing the randomUser API to create a JSON file or URL that can be integrated into I ...

Sharing information between a controller and a service in AngularJS

First: Check out this plunk. In my current project, I am working on developing a simple sign-up application using AngularJS that is hosted on a SharePoint site. To retrieve the current user data, I have implemented a factory method as shown below: app.f ...

Storing data in the browser's local storage using jQuery without requiring any CSS

I have a form that receives data and I am trying to save the first two pages of received data into localStorage: <form id="myForm" method="post"> Font Size (px): <input id="fontsize" type="text" name="fontsize" /> </form> <s ...

Using Vue Formulate to effortlessly upload multiple images

One of my projects involves using a Vue Formulate component for uploading multiple images to an Express.js backend. Here is the code snippet for the Vue Formulate component: <FormulateInput type="image" name="property_ ...

Is it possible for an independent perl script to execute a function from a website's javascript?

Looking at this complex setup, I find myself in a situation where I must find a way to trigger the $.ajax function on a webpage using a separate Perl script. The scenario involves a webpage making $.ajax calls to a Perl file, which retrieves data and send ...

Angular: display many components with a click event

I'm trying to avoid rendering a new component or navigating to a different route, that's not what I want to do. Using a single variable with *ngIf to control component rendering isn't feasible because I can't predict how many variables ...

Tips on restricting users to choose dates that are later than the current date

Currently, I am working with Vue3 using the options API. After reviewing this StackBlitz, my question is regarding how to correctly set the :max value for a date-picker. Even though I have assigned :max as new Date(), I am still able to select dates that ...

Is there a way to preserve the original color format without converting it to RGB

When applying a hsl color in JavaScript, it ends up being converted to RGB instead of staying as an HSL color. document.body.style.backgroundColor = "hsl(0,100%,50%)" document.body.style.backgroundColor; // "rgb(255, 0, 0)" I wanted to set an HSL color a ...