doug doug - 3 months ago 8
AngularJS Question

replace angular app with another via $http

I am using Angular to try to replace my login form with a registration form when a user clicks "Sign up," but I can't seem to get the second form to interact with angular, since the controller loads before the second form.

As of right now, I'm using JQuery's html() function to replace the form, and if I were just using Jquery as a function, I'd just do the following:

$(window).on('click','submit',function(){
//function here
});


but I can't seem to get anything similar to work in Angular.

Original Form:

<div ng-app="login" ng-controller="loginCtrl">
<div id="formContainer">
<form ng-submit="loginSubmit()" id="loginForm" name="loginForm">
email: <input id="email" name="email" ng-model="email">
password: <input id="pw" name="pw" ng-model="pw">
<div class="row center">
<span ng-click="signup()" id="signupButton" class="button">Sign Up</span>
<span ng-click="login()" id="loginButton" class="button">Submit</span>
</div>
</form>
</div>
</div>


Registration Form:

<div ng-app="signup" ng-controller="signupCtrl" class="flexRow">
<form ng-submit="signupSubmit()" id="signupForm" name="signupForm">
email: <input name="signupEmail" ng-model="signupEmail" type="email">
password: <input name="signupPw" ng-model="signupPw">
first name: <input name="signupFirstName" ng-model="signupFirstName">
last name: <input name="signupLastName" ng-model="signupLastName">
<div>
<span ng-click="register()" id="register" class="button">Register</span>
</div>
</form>
</div>


Controller:

app.controller("loginCtrl",function($scope, $http){

//sign up
$scope.signup = function(){
$http({
method: "POST",
url: "/functions/signup",
data: {/* data in here */},
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}).then(
function successCallback(response){
$('#formContainer').html((response.data));
}, function errorCallback(response){
alert('error: \n'+ response.data);
}
);
}

//registration
$scope.register = function(){
$http({
method: "POST",
url: "/functions/register",
data: {/*data here */},
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}).then(
function successCallback(response){
$('#auth').html(response.data);
}, function errorCallback(response){
$('#auth').html('ERROR: ' + response.data);
}
);
}

});


Is there any way I can have the controller read the ng-click event on the dynamically added content?

Answer

Rule #1: Don't mix jQuery with Angular, especially in controllers.

You're breaking the Angular data binding by replacing the form contents with jQuery. Probably the easiest way to do what you are wanting to do is to have certain fields visible for existing users (username/password, and login button) and the other fields (for creating an account) visible when the signup button is clicked. This can be accomplished via a simple ng-show, and you don't need a second app for it (like you have listed in your example.)

<div ng-app="login" ng-controller="loginCtrl">
    <div id="formContainer">
        <form ng-show="!register" id="loginForm" name="loginForm">
            email: <input id="email" name="email" ng-model="email">
            password: <input id="pw" name="pw" ng-model="pw">
            <div class="row center">
                <span ng-click="signup()" id="signupButton" class="button">Sign Up</span>
                <span ng-click="login()" id="loginButton" class="button">Submit</span>
            </div>
        </form>
<form id="signupForm" name="signupForm">
    email: <input name="signupEmail" ng-model="signupEmail" type="email">
    password: <input name="signupPw" ng-model="signupPw">
    first name: <input name="signupFirstName" ng-model="signupFirstName">
    last name: <input name="signupLastName" ng-model="signupLastName">
    <div>
        <span ng-click="register()" id="register" class="button">Register</span>
    </div>
</form>
    </div>
</div>

And the controller...

app.controller("loginCtrl",function($scope, $http){

$scope.register = false;

$scope.signup = function(){
    $scope.register = !$scope.register;
};

//sign up
$scope.login= function(){
    $http({
        method: "POST",
        url: "/functions/login",
        data: {/* data in here */},
        headers: {'Content-Type': 'application/x-www-form-urlencoded'}
    }).then(
        function successCallback(response){
            //do something after success, like maybe redirect to a new page
        }, function errorCallback(response){
            alert('error: \n'+ response.data);
        }
    );
}

//registration
$scope.register = function(){
    $http({
        method: "POST",
        url: "/functions/register",
        data: {/*data here */},
        headers: {'Content-Type': 'application/x-www-form-urlencoded'}
    }).then(
        function successCallback(response){
            //do something after success, like maybe redirect to a new page
        }, function errorCallback(response){
            alert('error: \n'+ response.data);
        }
    );
}

});
Comments