How do you show validation errors returned from WebAPI? - angularjs

I am using latest version of angular.js and WebAPI & bootstrap.
Imagine a form with few textboxes & submit button. Once a user submits the form, data is validated by WebAPI call on server as we cant trust client side validations.
In API controller, we do all our business validations.
Assuming that data entered in all the textboxes are invalid:
How should i return error message from my WebAPI so that the form displays it properly ?
In normal MVC way without angular, this is easy. We can add errors to ModelState and the view will pick it and show the errors properly.

AngularJS has built in form validation:
WebApi
You can return errors in whatever format you want. I would recommend that the response should contain following information:
An error message describing the error
In which part of the request the error occured (Payload, url params, query params)
Which attribute triggered the error (email, password, ...)
The response should also have the correct error status code (400, 401, ...)
Client
Assume that your response looks like this:
{
"message": "Email is invalid",
"area": "payload",
"field": "email"
}
Create your form and make sure the name attribute is assigned, since in your form validation you will need the it. By now angular will append form validations states to your elements:
<input type="email" name="email" id="email" ng-model="user.email" ng-minlength="6" required />
You can now dynamically display error messages by accessing the validation fields:
<span ng-show="form.email.$error.required && form.email.$dirty">Email can not be empty</span>

The angular way is using form with the angular directive ng-valid. you can simply add it e.g. to your input:
<input type="text" ng-valid="myFunc()">
You can define myFunc() within your scope, do whatever you like and return a boolean value.
Now, just add ng-disabled to your submit button and bind it to angular's form $valid property:
<button type="submit" ng-disabled="!myForm.$valid">Cool Button</button>
Note: myForm is the name of your form.
Further information in the docs.

The solution for me was : https://stackoverflow.com/a/23087715/3290276
Just i needed to change two things 1)Get data and 2)low case the property modelState.
parseErrors(response.data)
function parseErrors(response) {
var errors = [];
for (var key in response.modelState) {
for (var i = 0; i < response.modelState[key].length; i++) {
errors.push(response.modelState[key][i]);
}
}
return errors;
}

Related

AngularJS and JAX-RS with ng-Grid

I am working on a AngularJS & JAX-RS application.(frankly am new to both)
On UI i have a ng-grid , each row has 3 columns , 1st a check box , 2nd Name , 3rd Age.
User can select rows from grid and click on "export to excel".
I am posting the whole data when user clicks on export to excel button
#POST
#PATH("/xlsExport")
#Consumes(MediaType.MULTIPART_FORM_DATA)
public Response excelExport(MultiPartFormData mfd) throws Exception {
System.out.ptrintln(mfd); // code not reaching here
}
Am getting exception "RESTEASY003065 : Cannot Consume Contet Type"
UI looks like
Also Tried
#POST
#PATH("/xlsExport")
#Consumes(MediaType.APPLICATION_JSON)
public Response excelExport(String mfd) throws Exception {
System.out.ptrintln(mfd); // code not reaching here
}
Same error
Also Tried
#POST
#PATH("/xlsExport")
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response excelExport(String mfd) throws Exception {
System.out.ptrintln(mfd); // incorrect values shown
}
This didn't give error, but also didn't give me all rows, just gives some incorrect values in .... so if i select 3 rows of 10 , i get some incorrect values in String as of now
Also Tried
#POST
#PATH("/xlsExport")
#Consumes(MediaType.APPLICATION_FORM_URLENCODED_TYPE)
public Response excelExport(#FormParam("id") Sting id) throws Exception {
System.out.ptrintln(id); // Compile time error
}
Same error
<form novalidate name="someForm" method="POST" action="/xlsExport">
...
<div class="ngHeaderContainer">
<div> <input class="ngSelectoionHeader" .../> </div> <!-- checkbox -->
<div> Name </div>
<div> Age </div>
</div>
<input type="submit" value="Export">
</form>
Will appreciate if can get some help
How can i resolve the error
Is this the best way to do it , cant i consume data in JSON
In order to send JSON (you're currently sending application/x-www-form-urlencoded but who knows what the plain HTML data looks like), you will need to handle the form submit event in your front-end app.
To do this, remove the action attribute and use ng-submit to call a controller function which uses $http or similar to post the data...
<form novalidate name="someForm" ng-submit="submit()">
and something like this in your controller
$scope.submit = function() {
$http.post('/xlsExport', $scope.someDataModel).then(res => {
// handle the response here
});
};

How to make parsleyjs only trigger validation on blur (for a field that has already failed validation)

I'm trying to figure out how to make parsleyjs only trigger validation on blur for a field that has already failed validation.
See http://jsfiddle.net/billyroebuck/zbmv2d3w/
Markup:
<form id="myform">
<label for="email">Email</label>
<input type="email" name="email"
data-parsley-required="true"
data-parsley-type="email"
data-parsley-custom
data-parsley-trigger="blur"
/>
<input type="submit" />
</form>
JavaScript:
window.Parsley.addValidator('custom',
function (value, requirement) {
console.log('custom validation triggered');
sleepFor(3000); // simulate a delay (testing only)
if (value == 'test#test.com') {
console.log('custom validation failed');
return false;
}
console.log('custom validation passed');
return true;
}, 32)
.addMessage('en', 'custom', 'custom validation failed');
$('#myform').parsley();
function sleepFor(sleepDuration) {
console.log('pretend this takes a while...');
var now = new Date().getTime();
while (new Date().getTime() < now + sleepDuration) { /* do nothing */
}
}
parsleyjs Version 2.2.0-rc1
The email field has validation rules to check:
a value is provided,
the value entered is a valid email address,
some custom rule (pretend this is an AJAX request)
I have the parsley-trigger attribute for this field set to blur.
Steps:
Open the console
Enter "a#b.com" in the email field above and press tab
Note the custom validation is triggered (good)
Enter "xyz" in the email field and press tab
Note the parsley type validation kicks in (good)
Enter "xyz#test.com" in the email field View the console
Note the custom validation is triggered the moment the input becomes a
valid email (in this case when you press the letter c in .com) vs
blur :(
How can I make sure the validation is only triggered on the blur event for invalid fields?
Thanks in advance!
I'm afraid there is no such option currently. The idea is to remove the error message as soon as possible and everyone appears to like this.

Post full form data to a service in Angular

I have a form that contains a lot of fields and I want to post all the form fields to a service using a post method. But I would like to send the whole form object and not to write one property by one. If I try to post the object that contains all my fields $scope.formData it also contains all the angular stuff inside like errors. What I need is a collection of field names and values. How can I achieve this with minimum coding?
Edit:
I ended up writing my own function:
function getAngularFormFields(form) {
var dictionary = { form: {} };
for (var key in form) {
if (form.hasOwnProperty(key) && !key.indexOf('$') == 0) {
dictionary.form[key] = form[key].$modelValue;
}
}
return dictionary;
}
Normally if you need to post a form you could just use the default method provided by your browser. This will send the form data, via POST, to your URL.
<form action="yourUrlHere" method="POST">
First name: <input type="text" name="fname">
Last name: <input type="text" name="lname">
<input type="submit" value="Submit">
</form>

Show Validation Summary in AngularJS on Form Submit

Is it possible to show a Validation Summary, a Div on top of the page with all the Validation error messages in angularjs , on form submit ?
I am coming from a .Net background and used to have a validation summary concept,all the examples i have seen in angular shows the error message right next to the control.
I am very new to angularjs , so an example or pointer to the right direction would be appreciated !
Thanks !
Yeah, you can use flags on each of your input fields, which will show a specific error message based on whether that flag is true or false.
For example:
<div ng-controller="signupCtrl">
<input type="text" id="username">
<input type="text" id="password">
<button ng-click="validate()">Sign-up</button>
</div>
Then, the validate function would run several other functions that would set flags. For example:
function signupCtrl($scope) {
$scope.validate = function() {
if( /* username is bad */ ) {
$scope.usernameError = true;
} else if ( /* password is bad */ ) {
$scope.passwordError = true;
} else {
// AJAX call to submit sign-up, or whatever
}
}
}
Your error messages would look like this:
<div class="error" ng-show="usernameError">Your username is bad</div>
<div class="error" ng-show="passwordError">Your password is bad</div>
Or, better yet, you can use a model, and only one error message:
<div class="error" ng-show="error">You {{field}} is bad</div>
But that second option would require some different tweaking of your code.

In Ajax->submit how to find the submission was success

I have a view that contains a hidden <div>. I show the hidden <div>, and when I click on submit in the hidden <div>, I want to know the whether the result is a success or failure.
In case of failure the <div> must not hide. Right now, it is always hidden.
Sample code:
var element = document.getElementById(element_id);
element.innerHTML = '<p><em>Loading ...</em></p>';
xmlhttp.open("GET", fragment_url);
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
element.innerHTML = xmlhttp.responseText;
}
}
xmlhttp.send(null);
xmlhttp.readyState change when your Ajax request is processed and the server responds.
xmlhttp.status gives you the return code from the server
xmlhttp.responseText gives you the response from the server - you can use this to ascertain whether your business logic is a success or a failure (send some error msg and check for it here)
#Cherian & #Pradeep failed to mention that you should intercept the onsubmit handler for your form. This handler should do the AJAX style form submission and prevent the default submission by returning 'false'.
<form action="submissionurl" method="post" onsubmit="formHandler(); return false;">
...
</form>
I'd also recommend the use of jquery, as it simplifies your code by a huge amountsubmit

Resources