2

I have a login page where I enter the credentials. When correct credentials are sent to the server, the server responses with string that contain new elements including scripts. The element set returned by the server then replaces the body content of the login page. The problem is that when the new content is loaded into the document angular functions don't work.

This is the login page:

<!DOCTYPE html>
    <html>
        <head>
        </head>
        <body ng-app="loginApp">
            <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
            <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
            <script type="text/javascript" src="js/login/loginMain.js">
            </script>
            Login<br><br>
            <form ng-controller="loginController" ng-submit="postForm()">
                User Name:<br>
                <input ng-model="unameInputField" type="text" name="user[name]"><br>
                Password:<br>
                <input ng-model="passwordInputField" type="password" name="user[password]">
                <input type="submit" name="Submit">
            </form>
        </body>
    </html>

and this is loginMain.js :

/* public/js/controllers/apps *************************************/
angular.module("loginApp", []); 

angular.module("loginApp").controller("loginController", function($scope, $http){
    $scope.unameInputField = "";
    $scope.passwordInputField = "";
    $scope.postForm = function() {
        $http.post("/credentials.json", {username: $scope.unameInputField, password: $scope.passwordInputField},
         {headers: {'Content-Type': 'application/json'}}).then(
                function(res) { //Success
                    // window.location.href = 'http://localhost:3000/home';
                    console.log(res.data)
                    $("body").attr("ng-app", "myApp");
                    $("body").html(res.data);
                },
                function(res) { // Failed
                    alert("POST FAILED, Server is most probably offline")
                }
            )
    }
}) 

This is the html elements I want to place inside the body element:

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
    <script type="text/javascript" src="js/main.js"></script>
    <title>Home Electricity Manager </title>    
    <h1 id="the-header">Wellcome to home electricity manager radoslav.k.marinov@gmail.com!</h1>
    <div id="button-1-div" ng-controller="myController" order="1" style="text-align: center; display: inline-block;" ng-init="spanText=S4555">
        <span id="button-1-span-1" ng-click="changeText()" style="white-space:pre;">{{spanText}}</span><br>
        <button id="butt-1" ng-style="myStyle" ng-click="toggleRelay()">{{ButtonStatus}}</button>
    </div><br>
    <div id="button-2-div" ng-controller="myController" style="text-align: center; display: inline-block;"> 
        <span id="button-2-span-2" ng-click="changeText()" style="white-space:pre;">{{spanText}}</span><br>
        <button id="butt-2" ng-style="myStyle" ng-click="toggleRelay()">{{ButtonStatus}}</button>
    </div><br>
    <div change-cred></div>

I see in the developers view of the Chrome Browser that the content is actually replaced but the user view looks like angular doesn't compile the new content. This is the picture of the page:

enter image description here

While if the angular functions are working properly the user page would look like this:

enter image description here

Excuse my bad English! I hope you get the idea and what is the problem indeed!

Hairi
  • 3,318
  • 2
  • 29
  • 68

1 Answers1

1

First: please, don't do this. Really. You are trying to reinvent something angular routing would already provide you. Invest some time studying the concepts behind views and either angularjs default routing scheme OR the advanced UI-Router module. It will save you a lot of pain later. What you are trying to do is basically creating a "login" state that your app gets redirected to when the user is not yet logged in... and there are plenty of samples of doing that with angularjs routing.

As for your original question... I think this is the expected result. I suspect that since you are adding HTML elements dynamically to the body when your second angularjs app (which I assume is defined in main.js) gets initialized it fails to recognize the current page content. This means that even if the app manages to start the initial compilation phase doesn't work as expected, ending up in an html page that isn't bound to the current scope.

If I really needed something similar to this solution, I would do two things:

  • add some feedback in the form of some alert() or console.log() calls to the main.js file, so that I can be sure that it gets executed.
  • try to force a manual compilation of the "view". Angularjs compile providers provide a $compile method that could be used for this purpose... but getting it to work in your specific case I fear will be a pretty daring task (the only time I had to use $compile was inside a custom directive, in order to process dynamic DOM changes performed by a JQuery plugin).

I hope this sheds some light. Anyway, at the cost of seeming redundant... I once again advise in not following this approach and instead using UI-Router.

SPArcheon
  • 1,273
  • 1
  • 19
  • 36