3

I have two angular apps as part of my application. The first app is basically just the login page, and the second app is everything else. The two apps share a couple of services, including one that controls the login information/logic.

The problem occurs when a user makes use of the "remember me" functionality. We want them to be automatically logged in when they browse to the login page and redirected to the logged-in status page. The automatically logged-in bit works fine, but when we attempt to redirect the user to the status page, which is in the second app, they get stuck in an infinite loop where the login page refreshes over and over. (Interestingly, if the user is not logged in, enters the appropriate login info and clicks the

It seems that the redirect works, because the url does update correctly and the page refreshes, but the content is wrong (still the old controller and view), so it keeps re-doing the same thing-- check to see if logged in, redirect if so. How can I make sure that I actually transfer to the second app and load the right view/controller on a redirect?

Code:

twPublicApp.controller('PublicLoginCtrl', function ($scope, $http, LoginData, BrowserStorageService, $window, $location) {
    window.changeApiRoot('/api/');

    $scope.username = '';
    $scope.password = '';
    $scope.remember = false;
    $scope.errorMessage = '';
    $scope.authenticating = false;

    if (LoginData.get('SessionToken', null, true) !== null) {
        // Check if still has a valid session
        $scope.authenticating = true;
        LoginData.checkSession(LoginData.get('SessionToken'), LoginData.get('Location'))
            .success(function(data) {
                if (data.Result === true) {
                    console.log('User looks to be already logged in... sending on');
                    BrowserStorageService.changeStore('localStorage');
                    LoginData.set(data);

                    //This is the line giving me problems.  I've tried these two versions, and a few others, and nothing seems to work properly.
                    //window.location.href = '/console#/status';
                    $window.location = '/console#/status';

                    $scope.authenticating = false;
                } else {
                    $scope.authenticating = false;
                    LoginData.set({});
                }
            })
            .error(function(jqXHR, textStatus, errorThrown) {
                $scope.authenticating = false;
                LoginData.set({});
            });
    }

    $scope.authenticate = function() {
        $scope.authenticating = true;
        LoginData.authenticate($scope.username, $scope.password,  $scope.remember)
            .success(function(data) {
                if (data.Result === true) {
                    if ($scope.remember) {
                        BrowserStorageService.changeStore('localStorage');
                    } else {
                        BrowserStorageService.changeStore('sessionStorage');
                    }
                    LoginData.set(data);

                    //Interestingly, this line works perfectly.
                    window.location.href = '/console#/status';

                    return;
                }
                $scope.authenticating = false;
            })
            .error(function(jqXHR, textStatus, errorThrown) {
                $scope.authenticating = false;
            });
    };

});
senschen
  • 794
  • 10
  • 27
  • Define states for your URL's using routing and use angular's $location.path("yourUrlName") to navigate to status page. This will ensure that the controller values will get updated in the view. – Vivz Oct 17 '17 at 06:28
  • @Vivz I've tried that. The problem is that I want to move to a second angular app, not within the same one, so using states doesn't work. – senschen Oct 17 '17 at 11:00
  • Can you try to use [`$location.path(url)`](https://docs.angularjs.org/api/ng/service/$location#path) instead to set the URL? Also, it's hard to figure out the problem without seeing the rest of the code (a sample plunker would be nice), but you can debug to see if this is not caused by a call to [$browser.onUrlChange()](https://github.com/angular/angular.js/blob/15581287a4ec003680d158b303af07f5f16ffbf0/src/ng/location.js#L941) when the URL changes. – Samir Aguiar Oct 18 '17 at 15:36
  • @SamirAguiar I have tried `$location.path(url)` and that does not work either. I'm not sure I understand your suggestion about `$browser.onURLChange()`-- what are you telling me to do with that? Just watch to make sure the url is changing? I can tell that it is because it changes in the address bar. – senschen Oct 18 '17 at 16:34
  • @senschen I actually meant that as a _hint_ of where you could start debugging... If, however, you could provide a simple Plunker it would be easier since a lot of other things could be influencing this. – Samir Aguiar Oct 18 '17 at 16:48
  • @SamirAguiar You can find a plunker here: https://plnkr.co/edit/eSUGrQIK0aVRAGbIExD3 However, the redirect still doesn't work quite right. – senschen Oct 18 '17 at 19:38
  • @senschen I've changed the plunker a bit and it seems to be working, so I guess it doesn't reproduce your problem: https://plnkr.co/edit/E3X1YLn24zeghjjavbMW?p=preview – Samir Aguiar Oct 18 '17 at 21:19
  • @SamirAguiar Thanks for fixing the redirect. I thought I included all the relevant stuff in the plunker, but if it isn't duplicating then maybe I missed something. That's all the code that's in the app_public.js file though, aside from some extra stuff to set up analytics and do some data validation for when the user enters credentials instead of being automatically logged in. I wouldn't think the problem is in another file? – senschen Oct 19 '17 at 11:23
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/157062/discussion-between-samir-aguiar-and-senschen). – Samir Aguiar Oct 19 '17 at 11:58
  • what does the code do when `/console#/status` is suppose to load? Does it check the user is authenticated and if not redirects to the login page? If that's the case then perhaps the login page thinks the session is authenticated but `/console#/status` does not resulting in infinite redirects. – logee Oct 22 '17 at 23:05
  • @user2718281 as best as I can tell (I put debug statements in the logindata service) `/console#/status` is never checking to see it the user is authenticated. – senschen Oct 23 '17 at 14:53
  • You don't give enough information to resolve this. You state that the problem is only on the remember me functionality which only changes the `BrowserStorageService`. You don't state or show how the other app knows to pick up the localstorage information. I don't think there's anything wrong with the code you've shown. It redirects as expected but it's the other app that's causing the loop. – toxaq Mar 01 '18 at 02:47

4 Answers4

0

Using $window or $location to Redirect in AngularJS

I believe the above mentioned link will help you resolve your problem.

  • I saw that question, and its solution did not work for me. I think that the problem is related to having to switch between two angular apps. – senschen Oct 17 '17 at 11:02
0

Some guesses

  1. Try using $window OR window, not both.

  2. The if (LoginData.get('SessionToken', null, true) !== null) block may be running too soon. Try placing it in a $timeout block to see if it makes a different.

Guy Yogev
  • 861
  • 5
  • 14
  • I was using one or the other, I just had them both in the code sample to prevent the obvious "use $window" answers. Also, I tried putting that if block inside a timeout, it did not solve the issue. – senschen Oct 18 '17 at 11:18
0

It seems you LoginController App is fine but the when the user gets redirected to other page all the values you have specified like "authenticating" doesn't remain same there except session storage. I don't how you are authenticating user for login check if its based on any of these flags because your this piece of code is fine you. Keep in mind every time you change/redirect to other site every things gets bootstrapped again. Either share the other app basic code or make sure your session data(or how ever you are authenticating) is based on same data.

ieatbytes
  • 516
  • 1
  • 6
  • 13
  • It is definitely based on the same data-- there is a single LoginData service that is shared between the two apps. – senschen Oct 23 '17 at 11:10
  • then it seems to be some issue between authorization/authentication. – ieatbytes Oct 24 '17 at 13:33
  • You would think, but the authorization logic is never called for the status page, only on the login page. And there it correctly authenticates. I can tell because it makes the attempt to change pages. – senschen Oct 24 '17 at 14:06
0

I would like to point out first of all that the way you are handling things is not advisable. No matter how complex a project is handling it via one root application is easier in long run.

Now specific answer for your question.

Check things in $locationProvider so that there is no flicker etc. and there after redirect them to the page that handles the views for your second application.

$window.open('root_page_second_app.html', '_self');

this should work just fine.

Gandalf the White
  • 2,415
  • 2
  • 18
  • 39
  • For the particular requirements of the project, this is the only way to handle the login page. I agree it makes everything more complicated, but it can't be done in a single application. Also, your `$window.open()` suggestion gives me an error: `10 $digest() iterations reached. Aborting!` – senschen Oct 23 '17 at 12:21
  • That is happening because perhaps you are missing something and number of iterations are getting increased. This happens generally in cases when you are missing something and the function is getting called multiple times. It happened once with me when I forgot to handle checks properly therefore it was getting called infinite number of times. Please take a look at your code. – Gandalf the White Oct 23 '17 at 12:23
  • I fixed it so that the error no longer appears (had the wrong url in); however, the issue is still not resolved-- the reloading loop is still happening. – senschen Oct 23 '17 at 13:26
  • Can you make a fiddle with things I suggested, It is something I did myself so... – Gandalf the White Oct 24 '17 at 05:15