Preparing user context prior to executing controllers within AngularJS

I recently created an AngularJS application and integrated a REST API to fetch resources for the app. As part of the authentication process, I store the user's access token in a cookie. When the user reloads the page, I need to retrieve user information from the token using the following code snippet:

mymodule.run(function ($rootScope, $cookies, AuthService, Restangular) {
    if ($cookies.usertoken) {
        // call GET api/account/
        Restangular.one('account', '').get().then( function(user) {
            AuthService.setCurrentUser(user);
        });
    }
});

The AuthService module looks like this:

mymodule.factory('AuthService', function($http, $rootScope) {
    var currentUser = null;

    return {
        setCurrentUser: function(user) {
            currentUser = user;
        },
        getCurrentUser: function() {
            return currentUser;
        }
    };
});

However, when a controller that requires the user variable is accessed:

mymodule.controller('DashboardCtrl', function (AuthService) {
     var user = AuthService.getCurrentUser();
});

The issue arises because the controller code gets executed before the API call completes, resulting in a null value for the user variable. Is there a recommended approach to ensure that the controllers wait for user data to load before initiating?

I came across this link, but I am interested in a more overarching method to initialize the application context.

Answer №1

One method I find useful for handling this scenario involves storing the promise returned by Restangular in a centralized location, such as on an object like `AuthService`, which can then be accessed later within the controller. To begin, you can add a property to `AuthService` to store the new promise:

return {
    authPromise: {},  // this will keep track of the Restangular promise
    // setCurrentUser, getCurrentUser
    // ...

When making the call to Restangular, save the promise and make sure to return the user data so that it can be retrieved later in the controller. Here's an example:

AuthService.authPromise = Restangular.one('account', '').get()
                          .then( function(user) {
                              AuthService.setCurrentUser(user);
                              return user; // <--important
                           });

Finally, set up a new promise in the controller that will assign the `user` variable once resolved:

mymodule.controller('DashboardCtrl', function (AuthService) {
    var user;
    AuthService.authPromise.then(function(resultUser){
        user = resultUser;
        alert(user);
        // perform actions with user
    });
});

Demonstration: You can check out a JSFiddle demo where I've simulated an AJAX request using `$timeout`. The promise resolves when the timeout is completed.

Answer №2

One potential approach is to centralize the authentication process within a parent controller. This can be implemented by calling the Authenticate() method on the parent controller in the resolve function of your routing configuration, like so:

resolve:DashboardCtrl.$parent.Authenticate()
.

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

Looking to set up an event handler for the browser's back button in next.js?

When my modal opens, it adds a hash to the URL like example.com/#modal. I want to be able to recognize when the back button is clicked in the browser so I can toggle the state of the modal. The challenge is that since I am using next.js (server-side rend ...

Is there an equivalent of getElementById for placeholder text?

I need help automating the input of information on a webpage using JavaScript. Each field has a unique ID, like this: <div id="cc-container" class="field has-float-label"> <input placeholder="ccnumber" id="credit_card_number" maxlength="16" ...

Can an entire object be bound to a model in an Angular controller function?

In TypeScript, I have defined the following Interface: interface Person { Id: number; FirstName: string; LastName: string; Age: number; } Within a .html partial file, there is an Angular directive ng-submit="submit()" on a form element. A ...

Using CSS or Javascript, you can eliminate the (textnode) from Github Gist lists

My goal is to extract the username and / values from a series of gists on Github Gists. The challenge lies in the fact that there are no identifiable classes or IDs for the / value. https://i.stack.imgur.com/9d0kl.png Below is the HTML snippet with a lin ...

Flag is activated to retrieve the data from the @Input source

@Input() config= []; flag = false; I need to change the flag to true only when I receive data in the config from the @input. Where should I do this? The data in the config is delayed and I am unable to access it in ngOnInit but can get it in ngOnChanges. ...

cancel the ongoing ajax request during a specific event

There seems to be an issue with the behavior of clicking on the .personalized class. When clicked, it does not display both #loading_personalized and #divPersonalized elements simultaneously. This results in the execution of an AJAX call even when the pr ...

Exploring the Overhead of Setting Up an HTTPS Connection

I am currently designing a web-based chat application that requires an AJAX request for every message sent or received. I want to ensure that the data is encrypted, and I am considering using HTTPS with long-polling for this purpose. Given the higher freq ...

The iFrame that is generated dynamically becomes null when accessed from a page that has been loaded using JQuery

One issue I am facing is with a dynamically created iframe in regular javascript. It functions perfectly fine when called from a static page using conventional methods. However, when it is being called from a page loaded by jQuery, I encounter an error s ...

What is the best way to save a PDF from within a frame using JavaScript and an HTML5 <embed> tag?

I'm looking for assistance with a script for my website that dynamically generates a PDF after the user makes selections in one of the frames. The website uses the HTML5 tag to display the PDF file. Can anyone provide guidance on a script that can: ...

Discover the method for populating Select2 dropdown with AJAX-loaded results

I have a basic select2 box that displays a dropdown menu. Now, I am looking for the most effective method to refresh the dropdown menu every time the select menu is opened by using the results of an AJAX call. The ajax call will yield: <option value=1 ...

When trying to access localhost:5000, the index.js file is unable to retrieve /

const NutritionAPI = require('./nutritionapi'); const nutService = new NutritionAPI('50cee42503b74b4693e3dc6fccff8725','2755697297a84ac5a702461b166e71f6'); // Setting up Express webhook const express = require('express&ap ...

Combining the power of Node.js and Node-MySQL with Express 4 and the versatile Mustache

Currently, I am delving into the world of Node.js and encountering a bit of a roadblock. My focus is on passing a query to Mustache. Index.js // Incorporate Express Framework var express = require('express'); // Integrate Mustache Template En ...

The reason for setting a variable as void 0 in JavaScript

Currently, I am delving into the libraries referenced in this particular article as well as other sources. There are some truly mind-boggling concepts contained within these resources, one of which is highlighted by the following line: var cb = void 0; I ...

Discover JQPlot: Visualize data sets and annotations sourced from an external location

I have been utilizing JQPlot to generate charts by extracting data from a database, similar to the example showcased here: . Currently, the chart functions smoothly; however, I am facing an issue with the series labels as they are hardcoded. Is there a wa ...

AJAX Image Upload: How to Transfer File Name to Server?

Has anyone successfully uploaded an image to a web server using AJAX, but struggled with passing the file name and path to the PHP script on the server side? Here is the HTML code along with the JavaScript (ImageUpload01.php) that triggers the PHP: Pleas ...

Utilizing AngularJS: Employing the $q Promise Feature to Await Data Readiness in this Scenario

I am currently facing an issue with my Controller and Factory. The Controller initiates an API call in the Factory, but I am struggling to make it wait for the data to be gathered before proceeding. This is where I believe implementing something like $q mi ...

Utilizing props in makeStyles for React styling

I have a component that looks like this: const MyComponent = (props) => { const classes = useStyles(props); return ( <div className={classes.divBackground} backgroundImageLink={props.product?.image} sx={{ position: "r ...

Why doesn't the error get translated into the model when I am utilizing ngModel.$setValidity?

Encountering an issue with nested directives and translating errors into the model. Check out the code sample here. .directive('myValidationDirective', [ function () { return { restrict: 'A', requir ...

Tips for automatically loading a new page or URL when a user scrolls to the bottom

I am working on implementing infinite scroll functionality, where a new page loads automatically when the user reaches the bottom of the page or a particular div. Currently, I have this code that loads a new page onclick. $("#about").click(function(){ ...

PHP's Encoding Woes Are Back in Action

I'm encountering encoding challenges on my website, and it's becoming quite frustrating. Allow me to elaborate My meta tag specifies utf8 as the charset. The scripts I'm using also have utf8 defined (<script type="text/javascript src=". ...