Issue with angular animation and undefined javascript values - javascript

I am trying to get an angular animation to be triggered upon an unsuccessful login (either when the server sends a 4xx (e.g. 403) or when no credentials are provided).
Here is the controller:
.controller('SigninCtrl', ['$scope', '$rootScope', '$cookies', '$state', '$animate', 'signinService', function ($scope, $rootScope, $cookies, $state, $animate, signinService) {
$scope.signin = function () {
$scope.shake = false;
if ($scope.credentials) {
signinService.signin($scope.credentials, function (status, memberRole) {
$scope.shake = false;
//TODO: necessary to check status?
if (status === 200) {
...
}
},
function () {
$scope.shake = true;
});
}
else {
//TODO: only shakes/works once!
$scope.shake = true;
}
}
}]);
The form:
<form class="form-signin" ng-class="{shake: shake}" name="signinForm" ng-submit="signin()" novalidate>
<h2 class="form-signin-heading signin-title">{{'SIGNIN' | translate}}</h2>
<input type="email" ng-required name="username" ng-model="credentials.username" class="form-control" placeholder="{{'SIGNIN_FORM_EMAIL'| translate}}"/>
<input type="password" ng-required name="password" ng-model="credentials.password" class="form-control" placeholder="{{'SIGNIN_FORM_PASSWORD'| translate}}"/>
<button class="btn btn-lg btn-primary btn-block" type="submit">{{'SIGNIN' | translate}}</button>
<div class="forgot-password">
<a ui-sref="sendpasswordresetinformation">{{'SIGNIN_FORM_FORGOTTEN_PASSWORD' | translate}}</a>
</div>
</form>
However, if the form has no credentials in the inputs (nothing as in not even the empty string) the form shakes only once.
Can someone please help?
edit 1:
.factory('signinService', ['$http', function ($http) {
return {
signin: function (credentials, successCallback, errorCallback) {
var transform = function (data) {
return $.param(data);
}
return $http.post('/api/signin', credentials, {
headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'},
transformRequest: transform
}).success(function (data, status, headers) {
if (status === 200) {
successCallback(status, headers('MEMBER_ROLE'));
}
else {
console.log('auth error');
successCallback('error');
}
}).error(function(data, status, headers) {
console.log("error!", data, status, headers);
errorCallback();
});
}
}
}]);
Changing the controller to :
...
$scope.signin = function () {
$scope.shake = false;
$scope.$apply();//ADDED!
...
fixed the issue. Thanks floribon...

Related

Textbox binding not working when page has loaded AngularJS [duplicate]

This question already has answers here:
How to get promise result using AngularJS
(2 answers)
Closed 3 years ago.
I'm trying to set textbox value based on the result of promise values when page has loaded. The values on textbox set only if I click on it and then out of it (just like blur event).
Controller
(function() {
'use strict'
var newPurchasingCardController = function($scope, $rootScope, $filter, $window, $location, $timeout, requestService) {
$scope.actionTitle = "";
$scope.gin = "";
$scope.fullName = "";
$scope.workEmail = "";
$scope.msg = "";
var getCurrentUserData = function () {
var dfd = new $.Deferred();
var queryUrl = _spPageContextInfo.webAbsoluteUrl + "/_api/SP.UserProfiles.PeopleManager/GetMyProperties";
$.ajax({
url: queryUrl,
method: "GET",
headers: { "Accept": "application/json; odata=verbose" },
success: onSuccess,
error: onError,
cache: false
});
function onSuccess(data) {
dfd.resolve(data);
}
function onError(data, errorCode, errorMessage) {
dfd.reject(errorMessage);
}
return dfd.promise();
}
var _init = function () {
$scope.actionTitle = "New Card Request"
var promise = getCurrentUserData();
promise.then(function (data) {
$.each(data.d.UserProfileProperties.results,function(i,property){
if(property.Key === "EmployeeNumber")
{
$scope.gin = property.Value;
}
if(property.Key === "FirstName")
{
$scope.fullName = property.Value;
}
else if (property.Key === "LastName") {
$scope.fullName += " " + property.Value;
}
if(property.Key === "WorkEmail") {
$scope.workEmail = property.Value;
}
console.log(property.Key+":"+property.Value);
});
}, function(error) {
console.log("An error has occurred trying to get employee information." + error);
});
}
$scope.$on('$viewContentLoaded', function(event)
{
_init();
});
}
angular.module('myApp').controller('newPurchasingCardController', ['$scope', '$rootScope', '$filter', '$window', '$location', '$timeout', 'requestService', createnewPurchasingCardController]);
}());
And in the html view I just have
HTML
<input ng-model="gin" type="gin" class="form-control" id="gin" placeholder="GIN">
<input ng-model="fullName" type="name" class="form-control" id="name" placeholder="Name">
<input ng-model="workEmail" type="email" class="form-control" id="email" placeholder="Email">
I have tried with viewContentLoaded but not working, what would be a good approach to accomplish this? Thanks.
You are mixing angularjs with Jquery and that causes all the problems.
Use $http service for get request : https://docs.angularjs.org/api/ng/service/$http#get
var getCurrentUserData = function () {
var queryUrl = _spPageContextInfo.webAbsoluteUrl + "/_api/SP.UserProfiles.PeopleManager/GetMyProperties";
$http({
url: queryUrl,
method: "GET",
headers: { "Accept": "application/json; odata=verbose" },
cache: false
})
.then(function(response) {
$scope.gin = response.data.EmployeeNumber;
// here set scope variables directly
})
.catch(function(response) {
console.error('error', response.status, response.data);
})
.finally(function() {
console.log("finally ");
});
}

How to implement angularjs async?

I am using AngularJS v1.5.8, My requirement is when i click the Next button it'll display 'Processing...' inside button as text before complete the operation, i have included the $q with my services to get the asynchronous facility, but not working. please see my below codes.
Service
mainApp.factory('PINVerificationServices', ['$http', '$rootScope','$q', function ($http, $rootScope) {
return {
IsPermitted: function (param) {
return $q($http({
url: '/Api/ApiPINVerification/IsPermitted/' + param,
method: 'POST',
async: true
}));
}
};
}]);
Controller
mainApp.controller('PINVerificationController', function ($scope, $rootScope, $state, $window,$q, PINVerificationServices) {
$scope.SubmitText = "Next";
$scope.Next = function () {
$scope.SubmitText = "Processing...";
PINVerificationServices.IsPermitted($scope.PIN).then(function (result) {
$scope.SubmitText = "Next";
});
}
}
HTML
<div class="list-group list-group-sm">
<div class="list-group-item">
<input class="form-control" ng-model="PIN" placeholder="PIN" required id="PIN" name="PIN" type="text" />
</div>
</div>
<button type="submit" ng-click="Next()">{{SubmitText}}</button>
Try this:
return $http({
method: 'POST',
url: '/Api/ApiPINVerification/IsPermitted/' + param
});
Make below changes (from your requirement of nested $http).
In factory Use only $http, and no need of $rootScope as well, It should be like :
mainApp.factory('PINVerificationServices', ['$http', function ($http) {
return {
IsPermitted: function (param) {
return $http({
url: '/Api/ApiPINVerification/IsPermitted/' + param,
method: 'POST'
});
},
GetStudentInformationByPIN : function () {
return $http({
url: '/Api/ApiPINVerification/GetStudentInformationByPIN /',//your api url
method: 'GET'
});
}
};
}]);
In controller make use of $q.all() :
mainApp.controller('PINVerificationController', function ($scope, $rootScope, $state, $window,$q, PINVerificationServices) {
$scope.SubmitText = "Next";
$scope.Next = function () {
$scope.SubmitText = "Processing...";
$q.all([PINVerificationServices.IsPermitted($scope.PIN),
PINVerificationServices.GetStudentInformationByPIN($scope.PI‌N),
//other promises
]).then(function (result) {
if(result[0].data){
$scope.SubmitText = "Next";
}
if(result[1].data){
// studentdata response handling
}
});
}
}

Issue with populating partial view with AngularJs and MVC

I am new to AngularJs. I am using a partial view for Create and Edit operation but facing some issue wile retrieving the data.
The data is being retrieved successfully from my MVC controller but is unable to populate the view.
Here is the JS I am using
(function (angular) {
'use strict';
angular.module('Sub_Ledger_Category_Create_app', [])
.controller('Sub_Ledger_Category_Create_ctrl', function ($scope, $http, $location) {
$scope.SubLedgerCategoryModel = {};
GetRequestType();
function GetRequestType() {
$http.get('/Common/Get_Action_Request')
.success(function (result) {
//debugger;
// $scope.SubLedgerCategoryModel = data;
if (result == "Create") {
$("#txt_Master_Subledger_Category").html("<h3 class='box-title'> Create Sub Ledger Category </h3>");
// $("#txt_Master_Accounting_Group_Group_id").val(0);
}
else {
$("#txt_Master_Subledger_Category").html("<h3 class='box-title'> Edit Sub Ledger Category</h3>");
//GetEditData();
$scope.GetEditData();
}
$("#Master_Subledger_Category").val(result)
NProgress.done();
})
.error(function (data, status, headers, config) {
NProgress.done();
$("div.failure").text("Unable to retrieve Request Type");
$("div.failure").fadeIn(300).delay(1500).fadeOut(400);
});
};
$scope.GetEditData = function () {
$http.get('/Master_Subledger_Category/GetEditData')
.success(function (data, status, headers, config) {
debugger;
$scope.SubLedgerCategoryModel = data;
console.log(data);
})
.error(function (data, status, headers, config) {
NProgress.done();
$("div.failure").text("Retrive Failure");
$("div.failure").fadeIn(300).delay(1500).fadeOut(400);
});
};
$scope.InsertSubledgerCategory = function () {
NProgress.start();
var Request_Type = $("#Master_Subledger_Category").val();
var Url_Master_Subledger;
if (Request_Type == "Create") {
Url_Master_Subledger = "/Master_Subledger_Category/Create_Master_Subledger_Category_Ajax";
}
else {
Url_Master_Subledger = "/Master_Subledger_Category/Test";
}
$http({
method: 'POST',
url: Url_Master_Subledger,
data: $scope.SubLedgerCategoryModel
}).success(function (data, status, headers, config) {
if (data.success === true) {
NProgress.done();
$("div.success").text("Successfully Created");
$("div.success").fadeIn(300).delay(1500).fadeOut(800);
$scope.SubLedgerCategoryModel = {};
console.log(data);
}
else {
NProgress.done();
$("div.failure").text("Saveing Failure");
$("div.failure").fadeIn(300).delay(1500).fadeOut(400);
}
}).error(function (data, status, headers, config) {
NProgress.done();
$("div.failure").text("Saveing Failure");
$("div.failure").fadeIn(300).delay(1500).fadeOut(400);
console.log($scope.message);
});
};
})
.config(function ($locationProvider, $sceProvider) {
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
$sceProvider.enabled(false);
});
})(angular);
Here is the HTML:
<div class="form-horizontal" ng-app="Sub_Ledger_Category_Create_app">
<div class="box-body" ng-controller="Sub_Ledger_Category_Create_ctrl">
<div class="form-group">
<label for="txt_Master_Subledger_Category_Name" class="col-sm-2 control-label">Sub Ledger Category</label>
<div class="col-sm-10">
<input class="form-control" ng-model="SubLedgerCategoryModel.Sub_Ledger_Cat_Name" id="txt_Master_Subledger_Category_Name" name="txt_Master_Subledger_Category_Name" autofocus placeholder="Sub Ledger Category">
<input ng-model="SubLedgerCategoryModel.Sub_Ledger_Cat_ID" name="txt_Master_Subledger_Category_ID" id="txt_Master_Subledger_Category_ID" hidden />
</div>
</div>
<!-- /.box-body -->
<div class="box-footer">
<button type="submit" value="Save" ng-click="InsertSubledgerCategory()" class="btn btn-info pull-right">Save</button>
<div class="text-red alert-box failure pull-right margin-r-5"></div>
<div class="text-green alert-box success pull-right margin-r-5"></div>
</div>
<!-- /.box-footer -->
</div>
</div>
Unfortunately I am unable to populate the view but in Console log I am able to view the data, helpful if anybody and help me.
AngularJs prevents loading HTML in this way by default. You might be getting an error on browser console: attempting to use an unsafe value in a safe context.
This is due to Angular's Strict Contextual Escaping (SCE) mode (enabled by default). Have a look to this for more information.
To resolve this issue you have 2 solutions:
$sce
$scope.thisCanBeusedInsideNgBindHtml = $sce.trustAsHtml(someHtmlVar);
ngSanitize: include the angular-sanitize.min.js resource and add the dependency in module.
hope this will help.
I have only changed the following
scope.SubLedgerCategoryModel = data;
to
scope.SubLedgerCategoryModel = data[0]:
and its resolved my issue.

Show data after POST with AngularJS

Im trying show the data that I have enterd, after an POST-action. But it does not work. How can I accomplish this?
Here is my HTML:
<div ng-controller="Test">
<div class="container">
<div class="col-sm-9 col-sm-offset-2">
<div class="page-header"><h1>Testar</h1></div>
<table class="table table-striped table-condensed">
<thead>
<tr>
<th>Namn</th>
<th>Efternamn</th>
<th>E-post</th>
</tr>
</thead>
<tr ng-repeat="info in test.data"><td>{{info.namn}}</td><td>{{info.efternamn}}</td><td>{{info.email}}</td></tr>
</table>
<form name="userForm" ng-submit="submitForm(userForm.$valid)" novalidate> <!-- novalidate prevents HTML5 validation since we will be validating ourselves -->
<div class="form-group" ng-class="{'has-error' : userForm.name.$invalid && !userForm.name.$pristine, 'has-success' : userForm.name.$valid }">
<label>Name</label>
<input type="text" name="name" class="form-control" ng-model="form.name" required>
<p ng-show="userForm.name.$invalid && !userForm.name.$pristine" class="help-block">Fel namn</p>
</div>
<div class="form-group" ng-class="{'has-error' : userForm.username.$invalid && !userForm.username.$pristine, 'has-success' : userForm.username.$valid && !userForm.username.$pristine}">
<label>Username</label>
<input type="text" name="username" class="form-control" ng-model="form.username" ng-minlength="3" ng-maxlength="8">
<p ng-show="userForm.username.$error.minlength" class="help-block">För kort</p>
<p ng-show="userForm.username.$error.maxlength" class="help-block">För långt</p>
</div>
<div class="form-group" ng-class="{'has-error' : userForm.email.$invalid && !userForm.email.$pristine, 'has-success' : userForm.email.$valid && !userForm.email.$pristine}">
<label>Email</label>
<input type="email" name="email" class="form-control" ng-model="form.email">
<p ng-show="userForm.email.$invalid && !userForm.email.$pristine" class="help-block">Ange korrekt e-post</p>
</div>
<button type="submit" class="btn btn-primary">Lägg till</button>
</form>
</div>
</div>
Here is my Controller:
as.controller('Test', function($scope, $http, $rootScope)
{
$http.get($rootScope.appUrl + '/nao/test/test')
.success(function(data, status, headers, config) {
$scope.test = data;
});
$scope.form = {};
$scope.submitForm = function(isValid) {
if(isValid)
{
$http.post($rootScope.appUrl + '/nao/test', $scope.form)
.success(function(data, status, headers, config) {
console.log(data);
$scope.test = data;
}).error(function(data, status) {
})
}
};
});
How can I view the data that I entered in the input fields, after the submit? As you can see, I've tried to set $scope.test = data, but that don't work.
You need to create a factory method for your $http post call which will return the data to the controller when you inject the factory.
angular.module('your factory module', [])
.factory('testFactory', function($http) {
return {
urMethod: function(callback) {
return $http({
<ur http call parameters>
}).
success(function(data) {
callback(data);
});
}
};
});
and in your controller:
as.controller('Test', ['testFactory', function($scope, $http, $rootScope,testFactory)
{
$http.get($rootScope.appUrl + '/nao/test/test')
.success(function(data, status, headers, config) {
$scope.test = data;
});
$scope.form = {};
$scope.submitForm = function(isValid) {
if(isValid)
{
testFactory.urMethod(function(data){
$scope.test = data;
});
}
};
}]);
please see here : http://jsbin.com/gagiwo/1/edit?js,output
as.controller('Test', function($scope, $http, $rootScope)
{
$http.get($rootScope.appUrl + '/nao/test/test')
.success(function(data, status, headers, config) {
$scope.test = data;
});
$scope.form = {};
$scope.submitForm = function(isValid) {
if(isValid)
{
$http.post($rootScope.appUrl + '/nao/test', $scope.form)
.success(function(data, status, headers, config) {
console.log(data); <-- data is object returned from server
$scope.datePosted = $scope.form; <-- $scope.form is your object posted to server
}).error(function(data, status) {
$scope.datePosted =$scope.form;
});
}
};
});

Prevent $watch to be called if element is not changed

I have this code in my Angular controller:
app.controller('CompaniesView', ['$scope', '$http', '$location', '$routeParams', '$route', 'noty', function($scope, $http, $location, $routeParams, $route, $noty) {
var id = "";
if ($routeParams.id !== undefined) {
id = '/' + $routeParams.id;
}
$http.get(Routing.generate('company-info') + id).success(function(data) {
if (data.message) {
$noty.error(data.message);
} else {
$scope.company = data.company;
$scope.status = data.status;
$scope.updStatus = $scope.company.status;
$scope.orderProp = 'name';
}
}).error(function(data, status, headers, config) {
if (status == '500') {
$noty.error("No hay conexión con el servidor");
}
});
$scope.$watch("updStatus", function() {
$http.post(Routing.generate('updateCompanyStatus'), {
'newStatus': $scope.updStatus
}).success(function(data) {
if (data.message) {
$noty.error(data.message);
}
}).error(function(data, status, headers, config) {
if (status == '500') {
$noty.error("No hay conexión con el servidor");
}
});
});
}]);
Any time I load the page the updStatus is called twice, so how I prevent the $watch to be executed and just call the function when the ng-model="updStates" changes? I have the same behavior with other controllers, I miss something at $watch docs? It's not supposed that this will only works if ng-model changes?
If you're using an ng-model it's usually easier to use the ng-change directive instead of $watch:
<input ng-model="foo" ng-change="fooChanged()"/>
Every time foo changes your fooChanged() function will be called.
Usually you put a check inside of the watch comparing previous an current value:
$scope.$watch("updStatus", function(newVal, oldVal) {
if (newVal != oldVal) {
$http.post(Routing.generate('updateCompanyStatus'), {
'newStatus': $scope.updStatus
}).success(function (data) {
if (data.message) {
$noty.error(data.message);
}
}).error(function (data, status, headers, config) {
if (status == '500') {
$noty.error("No hay conexión con el servidor");
}
});
}
});

Categories

Resources