AngularJS - managing routes prior to application launch

Is it okay to implement a Service within the $stateProvider for this purpose?

I have read various posts on stack overflow regarding routing, but most of them seem confusing, especially for beginners. Everyone seems to have a different approach, making it seem like rocket science. I want to develop good habits from the start and avoid bad ones...

Objective: run some functions before the application starts and, based on the output, route my end user accordingly.

What I have tried:

Implemented a Service >> AuthService | Actions >> simple check for:

  1. Fetching JWT token from the client Side (SQLite DB) - Token contains basic details + API Key
  2. Sending it to the server for authentication
  3. Receiving a response (Boolean)
  4. If Authorized >> load Home View. Otherwise, redirect to register View.
  5. Server-side validation takes place before loading any view

Service Providers

myApp.factory('AuthService', function (Session) {
         var authService = {};
          authService.isAuthorized = function(){
          return Session.authorized();
         };
        return authService;
 });


myApp.service('Session', function ($resource, $q, $timeout, URL_Config) {
  this.authorized = function () {
        var deferred = $q.defer();
        $timeout(function () {
            var db = window.openDatabase("config.db", "1.0", "Config", 2 * 1024 * 1024);
            db.transaction(function (tx) {
                tx.executeSql("SELECT * FROM user_details", [], function (tx, data) {
                    var token = data.rows.item(0).token;
                    var request = $resource(URL_Config.BASE_URL + '/authCheck', {token: token },
                        { query: {
                            isArray: false,
                            method: 'GET'
                        } });
                    request.query(function (res) {
                        if (res.error) {
                            deferred.resolve(false);
                        } else {
                            deferred.resolve(true);
                        }
                    });

                }, function (e) {
                    deferred.resolve(false);
                });
            });
        }, 500);
        return deferred.promise;
    };

 return this;
 });

Route Configuration

This is the part I am struggling with. Where and how should I inject this Service? I managed to get it working, but I'm unsure if this is the correct way to handle it.

  • Should I call the Service within the Resolve Property of $stateProvider?
  • Based on the value of AuthService, should I redirect to a view?
  • Should this process happen before the application starts?

myApp.config(function($stateProvider, $urlRouterProvider) {
   $urlRouterProvider.otherwise('/home');
   $stateProvider
    .state('home', {
        url: '/home',
        templateUrl: 'templates/home.html',
        controller: 'MainController',
        resolve: ['AuthService', function(AuthService, $location, $q){
            var deferred = $q.defer();
            var authChk = AuthService.isAuthorized(); 
            authChk.then(function(data){
                if(!data){
                    $location.path('/register'); 
                    deferred.resolve();
                } else{
                    $location.path('/home');
                    deferred.resolve();
                }
            }, function(e){
                $location.path('/register');
                deferred.resolve();
            });
            return deferred.promise;
        }]
    })
    .state('register', {
        url: '/register',
        templateUrl: 'templates/register.html',
        controller  : 'RegisterController',
        resolve: ['AuthService', function(AuthService, $location, $q){
            var deferred = $q.defer();
            var authChk = AuthService.isAuthorized();
            authChk.then(function(data){
                if(!data){
                    $location.path('/register');
                    deferred.resolve();
                } else{
                    $location.path('/home');
                    deferred.resolve();
                }
            }, function(e){
                $location.path('/register');
                deferred.resolve();
            });
            return deferred.promise;
        }]
    })
});

Is this the proper place to run such Authentication validation?

This is a simple Hello World demo to help me get started with Angular. I don't have navigation (multiple views), so the check should be straightforward.

I have seen many examples using locationChangeStart to fire a service before a view is loaded. Then $scope.watch and $broadcast are used when handling sessions (which is not the case here), but might be useful for future use.

Thank you. Any advice on how and where to handle this scenario is welcomed.

Answer №1

It was necessary for me to implement this as well. Utilizing the resolve for each state is key.

Outlined below is a function called resolveUserAuth which retrieves the user object.

 var resolveUserAuth = {
    'userAuth': function (AuthService, $rootScope) {
      if ($rootScope.user) {
        return $rootScope.user;
      } else {
        return myApp._getUserAuth(AuthService, $rootScope);
      }
    }
  };

  $stateProvider
    .state('login', {
      url: '/login',
      templateUrl: 'views/login.html',
      controller: 'LoginCtrl'
    })
    .state('logout', {
      url: '/logout',
      templateUrl: 'views/login.html',
      controller: 'LoginCtrl'
    })
    .state('home', {
      url: '/home',
      templateUrl: 'views/home.html',
      controller: 'HomeCtrl',
      resolve: resolveUserAuth
    })

getUserAuth

myApp._getUserAuth = function (service, rootScope) {
  return service.getRole().then(function () {
    service.getUser().then(function (user) {
      rootScope.user = user;
    });
  });
};

Login

 service.login = function (data) {
    var promise = $http.post('/auth/login', data).then(function (response) { // Success
      $rootScope.user = response.data;
      AssignedService.get({},
        function(assigned) {
          $rootScope.assigned = assigned;
          $rootScope.showLogin = false;
        }, function(error) {
          if (console && console.error) {
            console.error('Error getting assigned: ', error);
          }
        }
      );
      return response;
    }, function() { // Error
      $rootScope.showAlert('Unable to login, please try again', 'danger');
    });

    return promise;
  };

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

Scrolling Container Following Down the Page, Halts at Its Own Bottom (Similar to Twitter)

I am facing an issue and need some help. I am working on creating a three-column page layout where the middle section is for posts, the right section is for links and references (a bit long), and the left section is fixed. My question is: How can I preven ...

How can I determine the length of the returned array after a successful jQuery Ajax

I am struggling with looping through the Array returned from PHP. However, when I use jQuery .length, it returns 'undefined'. 'undefined' PHP: $items = array(); $items["country"] = "North Korea", $items["fruits"] = array( ...

Converting a JavaScript function to work in TypeScript: a step-by-step guide

When writing it like this, using the this keyword is not possible. LoadDrawing(drawing_name) { this.glg.LoadWidgetFromURL(drawing_name, null, this.LoadCB,drawing_name); } LoadCB(drawing, drawing_name) { if (drawing == null) { return; ...

Is my jQuery code generating a large number of DOM objects?

I am currently developing a hex dumper in JavaScript to analyze the byte data of files provided by users. To properly display a preview of the file's data, I am utilizing methods to escape HTML characters as outlined in the highest-rated answer on thi ...

React App searching for unused static files

Currently, my React application is deployed on the Nginx web server. Accessing the application using the URL XX.XX.XX.XX works fine. However, I want to be able to access it through the URL XX.XX.XX.XX/myapp/frontend. To achieve this, I have set up a revers ...

Creating dynamic visual elements on a webpage using HTML: Video

As I continue to learn HTML, CSS, and JavaScript to create a basic website for educational purposes, I have successfully embedded a video stored in my drive using the video element on an HTML page. However, I now aim to also display the video's title, ...

How can you tap into local storage in CSS while utilizing a chrome extension?

Can I access local storage from a Chrome extension's options file using CSS? Is it possible to use JavaScript to define a variable that can be utilized in CSS, or is local storage only accessible through JavaScript? If local storage is restricted to J ...

Displaying Angular JS data in the Laravel application using the URL::route facade

I'm currently working on an Angular JS + Laravel Application. On one of the pages, I have a list of users that I fetch, and when a row is clicked, it redirects to the edit user page. Below is a snippet of my code: Blade Template <tbody> &l ...

Choose a specific <div> element from an external page using Ajax/PHP

I'm encountering a small issue. I am currently utilizing Ajax to dynamically load content from another page into a <div> element after detecting a change in a <select>. However, my specific requirement is to only load a particular <div& ...

The function 'transformArticles' is not recognized as a property of the object 'Article'

I'm encountering an issue with Typescript that I need help understanding. In my code, I have a route where I am importing a class called Article like this: import { Request, Response } from "express"; const appRoot = require("app-root-path"); import ...

Upgrading from ng-router to ui-router in the Angular-fullstack application

issue 1: url:/home, templateUrl: 'index.html is appearing twice. problem 2: views: templateUrl: 'views/partials/main.html is not visible at all. What am I doing wrong? How can I effectively incorporate ui-router into yeoman's angular-fulls ...

The canvas game's animation can only be activated one time

I am currently working on designing a straightforward canvas game: Here is the code snippet located on CodePen var canvas; var ctx; var x = 300; var y = 400; var r = 0; var mx = 0; var my = 0; var WIDTH = 600; var HEIGHT = 400; function circle(x,y,r) ...

Developing a Prototype for an Angular Directive

After following instructions from a question on Stack Overflow, I have updated my application configuration with the code snippet below: $provide.decorator('formDirective', function($delegate) { var directive = $delegate[0]; directive.contro ...

Hiding timestamps on an interactive transcript: A step-by-step guide

I am in the process of creating personalized interactive ebooks based on a similar website found here: This website utilizes a VTT file along with an audio file. Although the JavaScript code requires time stamps, I would like to hide them for better read ...

An issue occurred while deploying Docker on Railway services: Build Error

After successfully deploying my Django project on Railway, I decided to add SendGrid mail functionality using the django-sendgrid-v5 package. Everything worked fine in the development environment, including sending emails like user signups. However, when ...

Concerns regarding code coverage when testing asynchronous functions using nockjs and jest

In my latest project, I've created a basic unit test for making API calls using NockJS and Jest within a React application. Here's a snippet of the code: AjaxService.js export const AjaxService = { post: (url, data, headers) => { ...

Oops! Looks like node.js is throwing an error with the message "connect ECONNREFUSED"

After creating a node.js application that interacts with a locally installed MySQL database, I encountered an issue where running the app through CMD (npm start) returned the desired results, but testing it through Postman resulted in an error: connect E ...

"Autocomplete disable" feature malfunctioning on the final input field of all web pages

I'm dealing with a web application that has a login page. The username and password fields have the autocomplete attribute set to "off," as well as other variations like nope, new-password etc. However, it's still not working in Chrome version 62 ...

Having trouble implementing the jQuery UI layout plugin in my Angular.js app with routing, specifically on the second view

Currently, I am developing a simple angular.js application that involves two views: a HOME view and an ALT view. My goal is to incorporate a jQuery UI Layout plug-in on the ALT view in order to create a layout with North, South, East, and West regions. Ho ...

My component reference seems to have gone missing in angular2

Trying to load my Angular 2 app, I encountered this error: https://i.stack.imgur.com/FmgZE.png Despite having all the necessary files in place. https://i.stack.imgur.com/kj9cP.png Any suggestions on how to resolve this issue? Here is a snippet from ap ...