Form Submit using Angularjs to SpringMVC Controller using $http.post - angularjs

How to send multiple data from jsp to Springmvc controller to change password.
I wants to change password using angular js.
How to solve this?
Alert message showing properly but cannot call controller using post method.
My js code
myangu.controller('account', function($scope, $http) {
var submitvalue = $scope.detailspassword = function() {
alert($scope.confirmpassword + "" + $scope.newpassword + ""
+ $scope.existedpassword);
};
var submitvalue = function(request) {
};
var error = function(reason) {
alert("failure message: " + JSON.stringify({
reason : reason
}));
$scope.errormessage = "Something Wrong.Cannot Change Your Password";
};
$http.post('/java/updatepassword').then(submitvalue, error);
});
SpringMvc controller
#RequestMapping(value = "/updatepassword", method = RequestMethod.POST,produces="application/json")
public #ResponseBody String updatepassword(#RequestBody Users users) throws JSONException,NullPointerException,JsonGenerationException{
System.out.println("Updatedpassword"+users.getPassword());
return uservice.updatepassword(users);
}
Jsp page
<div class="divTablebody">
<div ng-controller="account">
<%-- <form:form action="/java/changepassword" method="POST" > --%>
<div>{{errormessage}}</div>
<div class="divTableRow">
<div class="divTableCell">Existed password:</div>
<div class="divTableCell">
<input type="password" placeholder="Existed Password"
id="Existedpw" ng-model="existedpassword">
</div>
</div>
<div class="divTableRow">
<div class="divTableCell">New password:</div>
<div class="divTableCell">
<input type="password" placeholder="New Password" id="newpw"
ng-model="newpassword">
</div>
</div>
<div class="divTableRow">
<div class="divTableCell">Password Confirmation:</div>
<div class="divTableCell">
<input type="password" placeholder="Confirm Password "
id="confirmpw" ng-model="confirmpassword">
</div>
</div>
<div class="divTableRow">
<div class="divTableCell">Save</div>
<div class="divTableCell">
<input type="submit" id="pwsubmit" ng-click="detailspassword()" name="Submit">
</div>
</div>

You need to pass the data in post call as second parameter.
var objPassword = {
existedpassword : $scope.existedpassword
newpassword : $scope.newpassword
newpassword : $scope.confirmpassword
}
$http.post('/java/updatepassword',objPassword).then(submitvalue, error);
For more Angular#POST
EDIT :
myangu.controller('account', ['$scope', '$http', function ($scope, $http) {
$scope.detailspassword = function () {
alert($scope.confirmpassword + "" + $scope.newpassword + "" + $scope.existedpassword);
var formData = { cpass: $scope.confirmpassword, newpass: $scope.newpassword, oldpass: $scope.existedpassword };
var error = function (responce) {
$scope.errormessage = "Unsuccessful";
};
$http.post('/java/updatepassword',formData).then(submitvalue, error);
};
}]);

I guess this scenario is: a user logged in and is going to change the password
how about try this,
modify your backend by receiving the old password, new password and userId from #RequestParams (or if you don't have userId then use whatever that are unique for each user like email to query user's information from your DB)
in Spring
#RequestMapping(value = "/updatepassword", method = RequestMethod.POST,produces="application/json")
public #ResponseBody String updatepassword(#RequestParam String userId, #RequestParam String existedPassword, #RequestParam String newPassword) {
// query user by userId and match if existedPassword from request param is the same as user.getPassword()
// if password is correct then update the password to the new password and
// return blabla
}
then take a look at controller in angular
// first check if $scope.newpassword is the same value as $scope.confirmpassword
// then send the following POST request
$http.post('/java/updatepassword',
{ params: {
"userId": userId, // as long as, the user logged in so you can get userId somehow
"existedPassword": $scope.existedpassword,
"newPassword": $scope.newpassword
}
})
.then(function successCallback(response) {
// success
}, function errorCallback(response) {
console.log(response);
});
Hope it can help you get alternative way to solve this :)

Related

How to send date as YYYY/mm/dd in get api request rather than long format 2019-12-09T18:15:00.000 in angularjs?

I am making a get api request in angularjs. My date format in api is yyyy/mm/dd but i cant be able to send my ng-model date value in such format.
How can this be achieved? Date is only sent as 2019-12-09T18:15:00.000.
My input is
<input type="date" ng-model="init" class="form-control">
<input type="date" ng-model="final" class="form-control">
And my api request is:
vm.fetchlist = function () {
var stockPayload = {
init: $scope.init,
final: '2019/11/14',
};
var url = 'http://demo/api/stocksalessummary";
var config = { params: stockPayload };
$http.get(url, config, { headers: { Authorization: 'Bearer ' + token } })
}
I tried sending date format in ng-click event but cant seem to work as i also have 2 date fields to pass
<button class="btn btn-link " ng-click="vm.fetchList(init | date:'yyyy/MM/dd');">GET</button>
Use the AngularJS date filter to format the date:
vm.fetchlist = function () {
var stockPayload = {
init: $filter("date")($scope.init,"yyyy/MM/dd")
final: '2019/11/14',
};
var url = "http://demo/api/stocksalessummary";
var config = {
params: stockPayload,
headers: { Authorization: 'Bearer ' + token }
};
$http.get(url, config);
}
Also the $http.get request needs to be formed correctly.
For more information, see
AngularJS date Filter API Reference
AngularJS $http Service Api Reference
you can iterate your data and format the Date
moment(date).format("YYYY MM DD");
I am new to angularjs or js but I want to present a simple solution for your issue and I also tested it. Below is the a simple way to solve your issue, but am sure there should be a clean way to fix this. Please see the code below
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js">
</script>
var myApp = angular.module("app", []);
myApp.controller('controller', function ($scope, $http) {
$scope.formatDate = function () {
var year = $scope.init.getFullYear();
var month = $scope.init.getMonth()+1;
var day = $scope.init.getDate();
var date = year+"/"+month+"/"+day;
var stockPayload = {
init: date,
final: '2019/11/14',
};
alert('The Date is '+ stockPayload.init);
}
});
<div ng-app="app" ng-controller="controller">
<input type="date" ng-model="init" class="form-control" datetime="yyyy/MM/dd">
<input type="button" ng-click="formatDate()" value="Get Date" />
</div>
and it is tested here and works
https://www.tutorialspoint.com/online_angularjs_editor.php
I did it by
<button class="submit" ng-click="vm.fetchStockSalesSummaryList(init| date : 'yyyy/MM/dd',final | date : 'yyyy/MM/dd');">
Adding this line of filter code every time given function is called..Thannk you

Ionic View Template Not Being Updated When $scope Variable Is Updated In Controller

I have an ionic app I'm testing the ability to check for fingerprint login. All this works, BUT when I check for whether a user has stored login credentials and get back the decrypted value, I want to SHOW a button that allows user to initiate fingerprint login.
The problem is, when I get back the success when gathering credentials from SecureStorage, I set a variable to show the button ($scope.canUseFingerprint) which is modeled to a button in the view using ng-if. BUT the button never shows up, UNLESS I type a single character into the email input again (there is no "change" function on the input).
I have inspected and it shows the variable is getting set to true, yet the button will not showup until a single character is entered into that email input.
Can someone take a look?
Here is my view:
<form name="loginForm" ng-submit="login(email, password)">
<label>Email</label>
<input type="text" ng-model="email" placeholder="typehere"></input>
<label>Password</label>
<input type="text" ng-model="password" placeholder="typehere"></input>
<button type="submit">Test Login</button>
<!--Below Button Won't Showup-->
<button type="button" ng-if="canUseFingerprint" ng-click="showFingerPrint()">Show Finger Print</button>
<button type="button" ng-click="testShowFingerPrint()">Test Show Button</button>
<button type="button" ng-click="clearKeys()">Clear All Keys</button>
</form>
Here is my controller:
$ionicPlatform.ready(function(){
$scope.canUseFingerprint = false; //Initialized to false
var ss = new cordova.plugins.SecureStorage(
function () {
console.log('Success');
// $scope.allowFingerprintLogin = true;
setTimeout(function(){
checkForLoginCreds(); //Checks for login credentials
},3000)
},
function (error) {
$scope.canUseFingerprint = false;
addLockScreen();
console.log('Error ' + error);
},
'my_app');
var checkForLoginCreds = function(){
ss.get(
function (value) {
console.log('Success, got ' + value);
// This should activate the button, but does nothing. It DOES get set to true. Only after typing single character in input does the button show.
$scope.canUseFingerprint = true;
},
function (error) { console.log('Error ' + error); },
'loginInfo');
}
})
To convert ss.get from a callback-based service to a promise-based service, use the AngularJS $q Service:
function ssGetPromise(ss,key) {
var deferred = $q.defer();
ss.get(
function (value) {
console.log('Success, got ' + value);
deferred.resolve(value);
},
function (error) {
console.log('Error ' + error);
deferred.reject(error);
},
key
);
return deferred.promise;
}
Usage:
ssGetPromise(ss,'loginInfo').then(function(value) {
$scope.canUseFingerprint = true;
});
The $q Service creates promises that are integrated with the AngularJS Framework. Only operations which are applied in the AngularJS execution context will benefit from AngularJS data-binding, exception handling, property watching, etc.

Protractor functional test does not update ng-model?

So in my basic angular app, I have a login form :
<form layout="column" class="form">
<md-input-container>
<label for="email" translate>login.email</label>
<input id="email" type="email" ng-model="login.user.email" />
<span ng-bind="login.user.email"></span>
</md-input-container>
<md-input-container>
<label for="password" translate>login.password</label>
<input id="password" type="password" ng-model="login.user.password" />
<span ng-bind="login.user.password"></span>
</md-input-container>
<md-button class="hbd-primary" ng-click="login.authenticate()" id="submit-button">
<span translate>login.connection</span>
</md-button>
</form>
I am currently writing functional tests with protractor and jasmine. Here is my login test :
it('should fail login with bogus credentials', function() {
page.emailInput.clear().then(function() {
page.emailInput.sendKeys('supermerchant#bogus.com');
});
expect(page.emailInput.getAttribute('value')).toBe('supermerchant#bogus.com');
page.passwordInput.clear().then(function() {
return page.passwordInput.sendKeys('boguspass');
})
.then(function() {
expect(page.passwordInput.getAttribute('value')).toBe('boguspass');
return page.submitButton.click();
})
.then(function() {
expect(page.alert.element(by.id("login-alert-text")).getText())
.toBe('Email ou mot de passe invalide');
});
});
My problem is with the sendKeys() method, even if it writes the email and password correctly (visually it is in the inputs), when it triggers login function I noticed something weird with the request params : the fields email and password of my object user are empty eg "". But when I check the inputs 'value' attribute, it is correctly filled eg "supermerchant#bogus.com" & "boguspass".
So I searched a lot but found nothing so far, I have no idea where the issue could be...
Any leads would be very appreciated !
EDIT: additional code from controller and service.
Login controller
var vm = this;
vm.errors = '';
vm.user = {email: 'a', password: 'a', remember: true};
/**
*
* Log the user in.
*
**/
function authenticate() {
vm.errors = '';
retrieveToken(vm.user);
};
/**
*
* Get the jwt token. Change state depending on status.
*
**/
function retrieveToken(user) {
authService.login(user)
.success(function(data, status, headers, config) {
saveToken(data.token);
$state.go('employee');
})
.error(function(data, status, headers, config) {
vm.errors = 'Email ou mot de passe invalide';
});
};
/**
*
* Store the authenticated user.
*
**/
function saveToken(dataToken) {
var token = jwtHelper.decodeToken(dataToken);
var user = {
id: token.id,
firstName: token.firstName,
lastName: token.lastName,
roles: token.roles,
token: dataToken
};
authService.setAuthentication(true, user);
};
authService
function auth($injector, constants) {
var _authenticated = false;
var _user = null;
var service = {
login: login,
isAuthenticated: isAuth,
setAuthentication: setAuth,
getToken: getToken
};
/**
*
* Get the user authentication jwt.
*
**/
function login(user) {
return $injector.get('$http')
.post(constants.baseApiUrl + 'authentication/login', user);
};
/**
*
* Return a boolean to check if user is connected to app.
*
**/
function isAuth() {
return _authenticated;
};
/**
*
* Set the current user authentication.
*
**/
function setAuth(auth, user) {
if (auth) {
_authenticated = true;
_user = user;
}
else if (auth === false) {
_authenticated = false;
_user = null;
}
};
EDIT2: When I set the fields email and password to anything, those values do not change when authenticating, even with the clear and sendKeys. But visually, the inputs are cleared and filled correctly. So I suspect the issue to be a data binding one. Maybe the two way binding is broken in some way.
EDIT3: Ok so under every inputs I added a span with a ng-binding to email and password model. When sendKeys and clear are used, the spans value do not change (eg 'a'). So there is a data binding issue ! Value change when I manually delete a character from the input.
In our tests, we use clear and sendKeys but on separate calls.
So for your case, try:
page.emailInput.clear();
page.emailInput.sendKeys('supermerchant#bogus.com');
Another approach - Protractor clear() not working
So after hours and hours, I got the solution.
When launching functional tests, I was using browser Sync and opened another browser to check if everything was ok.
Somewhat, after using browser sync option open: false and letting phantomjs doing it's magic, everything work. Not sure why it was an issue but it is now resolved !

While navigating to a page, data is not getting pre-filled

I am getting the data in the controller from firebase database using angularfire api and updating the profile.user object from that data.
Now the problem is After login when I am routing to profile.html page, data is not getting pre-filled for that user in the fields which he had saved earlier in the database.
Thank you.
//The controller code is:
.controller('ProfileController', function($rootScope, $timeout, $location, authObj, fbRef) {
var profile = this;
// Check the current user
var user = authObj.$getAuth();
// If no current user send to register page
if (!user) {
$location.path('/register');
return;
}
var userRef = fbRef.child('users').child(user.uid);
(function init() {
// show the message if User moves to profile page
$rootScope.alertInfo = {
title: 'You are successfully logged in!!',
detail: 'You are still logged in',
className: 'alert alert-success'
};
// Load user info
userRef.once('value', function(snap) {
profile.user = snap.val();
if (!profile.user) {
return;
}
});
})();
profile.updateProfile = function() {
userRef.set(profile.user, function onComplete() {
// show the message if write is successful
$rootScope.alertInfo = {
title: 'Successfully saved!',
detail: 'You are still logged in',
className: 'alert alert-success'
};
});
};
})
Corresponding route for this controller is:
.when('/profile', {
controller:'ProfileController as profile',
templateUrl:'view/profile.html'
})
View for this controller is(profile.html):
<form id="frmProfile" role="form">
<h2>Profile</h2>
<br />
<div class="form-group">
<label for="txtName">Name</label>
<input type="text" ng-model="profile.user.name" class="form-control" id="txtName" placeholder="Name" name="name" />
</div>
<div class="form-group">
<label for="ddlDino">Favorite Dinosaur</label>
<select id="ddlDino" ng-model="profile.user.favoriteDinosaur" name="favoriteDinosaur" class="form-control">
<option>None</option>
<option>Pteranodon</option>
<option>Lambeosaurus</option>
<option>Stegosaurus</option>
<option>Daspletosaurus</option>
</select>
</div>
<button type="submit" ng-click="profile.updateProfile(profile.user)" class="btn btn-primary">Update</button>
FirebaseRef.once is asynchronous and angular has no way of knowing it should digest when the data returns. You need to add $rootScope.$apply() inside the callback to update your program when the data returns. Alternatively, it is recommended to use AngularFire which will handle this type of thing for you.
// Load user info
userRef.once('value', function(snap) {
profile.user = snap.val();
if (!profile.user) {
return;
}
$rootScope.$apply()
});

Howto submit a form with Angular and displaying results on a different page

I'm trying to submit a form from a HTML page using angular.
My HTML code is:
<form role="search">
<input type="text" ng-model="searchSring">
<button type="submit" ng-click="searchPerson(searchString);">Get it!
</button>
</form>
The searchPerson function is calling some PHP page using Ajax and data is successfully retrieved from it.
What I want is when the user has clicked the Get it! button, he should be routed to another HTML page where I would like to display the results. I've tried using "action=" in the form and even calling window.location once Ajax completed to route to the next page. Every time the result is cleared. I've tried using factory with get/set, but this too clears the data on the second page after the window.location call.
Here's the factory code:
myApp.factory('searchService', function(){
var searchService = {};
var mySearchResult = {};
searchService.set = function(searchResult){
mySearchResult = searchResult;
}
searchService.get = function(text){
return mySearchResult;
}
return searchService;
});
CONTROLLER
myApp.controller('OnlineCVController', function($scope, searchService) {
$scope.searchPerson = function(personString) {
$.ajax({
url: "mySearch.php",
type: 'POST',
data: { Person: personString },
async: false, success: function (result) { searchService.set(result);
console.log(result);
window.location = "search.html";
}, error: function (result) { } });
}
Can anyone guide me further?

Resources