Sebastian Sulinski Sebastian Sulinski - 1 month ago 12
AngularJS Question

AngularJs and Controller alias

I tried to alias the AngularJS controller in the view, but for some strange reason - it does not seem to respond when I prefix the methods and properties - any idea what might be causing it?

Here's my view (I'm using it with Laravel 5.1):

@extends('admin.template.layout-login')

@section('content')

<div class="row">

<div class="large-6 medium-8 columns large-offset-3 medium-offset-2" ng-controller="LoginController as login">

<form
name="htmlForm"
class="panel hide"
ng-submit="login.submit()"
ng-class="{ 'show-block' : !login.isRequestCompleted() }"
novalidate
>

<label for="username">
Username: *
<ng-messages
for="htmlForm.username.$error"
class="hide"
ng-class="{ 'show-inline' : login.isSubmitted() }"
>
<ng-message
when="required"
class="warning"
>Please provide your email address</ng-message>
<ng-message
when="email"
class="warning"
>Invalid email address</ng-message>
<ng-message
when="unsuccessful"
class="warning"
>Incorrect login details</ng-message>
<ng-message
when="suspended"
class="warning"
>Your account has been suspended</ng-message>
</ng-messages>
</label>

<input
type="email"
ng-model="formData.username"
name="username"
id="username"
required
>

<label for="password">
Password: *
<ng-messages
for="htmlForm.password.$error"
class="hide"
ng-class="{ 'show-inline' : login.isSubmitted() }"
>
<ng-message
when="required"
class="warning"
>Please provide your password</ng-message>
<ng-message
when="password"
class="warning"
>Invalid password</ng-message>
</ng-messages>
</label>

<input
type="password"
ng-model="formData.password"
name="password"
id="password"
required
password
>

<label for="remember">
<input
type="checkbox"
ng-model="formData.remember"
name="remember"
id="remember"
> Remember Me
</label>

<input
type="submit"
class="small button"
value="SEND ENQUIRY"

ng-if="!login.isOutForDelivery()"
>
<button
type="button"
class="small button"
disabled
ng-if="login.isOutForDelivery()"
>
PLEASE WAIT <i class="fa fa-spinner fa-spin"></i>
</button>

</form>


<div
class="hide"
ng-class="{ 'show-block' : login.isRequestCompleted() }"
ng-bind-html="login.trustAsHtml(confirmation)"
></div>


</div>

</div>

@endsection


and here's the AngularJS controller module:

(function(window, angular, app) {

"use strict";

app.controller(
'LoginController',
[
'$scope',
'$controller',
'$window',
function(
$scope,
$controller,
$window
) {

angular.extend(this, $controller('FormController', { $scope: $scope }));

$scope.submit = function() {

if ( ! $scope.isValid()) return false;

$scope.data = {
username : $scope.formData.username,
password : $scope.formData.password
};

$scope.submitRequest(
'/admin',
$scope.data
)
.success(function(data, status, headers, config, statusText) {

$window.location.href = data.url;

})
.error(function(data, status, headers, config, statusText) {

$scope.validation(data);
$scope.endOutForDelivery();
return false;

});

};

}
]
);

})(window, window.angular, window.CmdSystem.App);


Plus the
FormController
that the previous extends:

(function(window, angular, app) {

"use strict";

app.controller(
'FormController',
[
'$scope',
'RequestService',
'ContentService',
function(
$scope,
RequestService,
ContentService
) {

$scope.outForDelivery = false;
$scope.requestCompleted = false;

$scope.submitRequest = function(url, formData) {

$scope.outForDelivery = true;

return RequestService.post(url, formData);

};

$scope.responseReceived = function() {

$scope.requestCompleted = true;
$scope.outForDelivery = false;

};

$scope.isResponseReceived = function() {

return $scope.requestCompleted && ! $scope.outForDelivery;

};

$scope.endOutForDelivery = function() {

$scope.outForDelivery = false;

};

$scope.trustAsHtml = ContentService.trustAsHtml;

$scope.isValid = function() {

return $scope.htmlForm.$valid;

};

$scope.isSubmitted = function() {

return $scope.htmlForm.$submitted &&
! $scope.isRequestCompleted();

};

$scope.isRequestCompleted = function() {

return $scope.requestCompleted;

};

$scope.isOutForDelivery = function() {

return $scope.outForDelivery;

};

$scope.validation = function(data) {

angular.forEach(data, function(value, key) {

this[key].$error[value] = true;

}, $scope.htmlForm);

};

}
]
);

})(window, window.angular, window.CmdSystem.App);

Answer Source

None of the methods are on the controller. They're all defined on the $scope. So you can't access them using the login alias, which refers to the controller, not to the scope.

If you want to be able to call

login.foo()

from the view, then the method must be set on the controller, not on the scope:

this.foo = function() { ... };