1

I have a completely separate (from backend) AngularJS app. It uses tokens (JWT) for authentication. I'm also using ui-router and Restangular.

My problem: I have a sidebar/profile area that displays information from the currently logged in user on every "page". It is implemented as a directive+controller and is outside of the ui-view directive context. Inside of the controller for this sidebar I'm making a request to get the profile information and attach it to the $scope. Now, when a user first visits the app that sidebar and controller get invoked and the request is made to get the profile information. However, if and since the user is not logged in, the request fails and no data is bound with the $scope.

In the meantime (notice this all happens really fast), the event listener (listening for $stateChangeSuccess from ui-router) determines that the user is not logged in (essentially if they don't have a token) and does a $state.go('login') to forward the user to the login view. The user logs in, and a $state.go('dashboard') is invoked to bring them back to the dashboard. However, being that sidebar is outside of the context of the router the controller for it is not instantiated again to cause a new request for profile information. So the sidebar is just empty with no profile information.

I'm aware that there are going to be several possible solutions to this, but I'm trying to find a descent one.

How would you architect an angular app in order to solve or avoid the problem I'm having?

P.S. I think I may be having analysis paralysis over this.

2 Answers 2

1

It's hard for me to answer without seeing your code specifically. If I understand correctly your directive is firing prior to the user logging in, and since there is no user profile, the side bar doesn't initiate correctly. What I would suggest is possibly doing an ng-if on the tag that fires the directive something like:

<side-bar ng-if='userData' />

That way the tag isn't inserted into the DOM until the userData exists and therefore doesn't fire the directive on the login page.

Sign up to request clarification or add additional context in comments.

2 Comments

hmm, in my case side-bar's own controller makes the request for 'userData'
Gotcha, it doesn't have to be 'userData' it could be a flag (userIsLoggedIn) on your "main controller" that is set to true when the user has successfully logged in. If you don't have a shared parent controller, you'll need to put it into a service so that the variable can be shared between your controllers.
0

Assuming that the sidebar is the highest angular controller in your application and the other controllers are nested inside it you should be able to put a function on it that will load the information that you need. Then you can call $rootScope.loadme() anywhere you inject $rootScope.

var mainMod = angular.module('mainMod',[]);

mainMod .controller('mainController', function($scope)
{
$scope.loadMe = function() 
{
//load stuff here
};
$scope.loadMe();
});


mainMod .controller('secondController', function($rootScope, $scope)
{
$rootScope.loadMe();
});

SudoCode probably wont work with copy paste but the idea should be sound.

2 Comments

There is an ng-app module that is technically the most parent. I am using the .run() function with $rootScope.$on('$stateChangeSuccess'). I don't have a controller defined for this app module because I haven't needed one yet but that is easily doable.
alternatively you could create a service/factory that is injected in all the other locations. all of my modules have at least one controller so I have no experience without one.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.