Post full form data to a service in Angular - angularjs

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>

Related

AngularJS doesnt show the value of object's property

this should be straight forward, just cant figure out why it's not working.
I receive data in this format from Web API 2 (captured from Chrome's debugger):
AngularJS code to render the results
(vm.reportParameters contains that structure on the screenshot with 2 nodes):
<form>
<div ng-repeat="param in vm.reportParameters" class="form-group">
<label>Name</label>
<input type="text" class="form-control" value="{{param.Name}}" />
</div>
</form>
The output (missing value of Name property, should display "Country"):
Any idea what I am missing here? Why the value is not shown?
// GET api/reports/5
// This action retrieves parameters of selected report by reportId
[ResponseType(typeof(ParametersModel))]
public IHttpActionResult Get(string reportId)
{
try
{
var manager = new ReportsManager();
var model = manager.GetReportParameters(reportId);
if (model == null || model.Parameters == null || model.Parameters.Count == 0)
{
return NotFound();
}
return Ok<ParametersModel>(model);
}
catch (Exception ex)
{
return InternalServerError(ex);
}
}
Thanks.
UPDATE
This garbage-alike data has this weird format with all these k__XXXXX
things because I had various attributes applied to the model for XML
Deserialization (in C# code). After I removed all these Serialization
attributes, the model became normal and clean as expected. Go guess :)
Use without expression, ng-model
<input type="text" class="form-control" ng-model="param.Name" />

Dynamic hidden fields values where model name is stored in database

I have a requirement in angular js application where I need to dynamically create hidden variables. Name and value attribute for these hidden fields will be from database. But rather than storing actual value of hidden field in database name of model is stored in a database.
I have written a test function as follows. TempVars will be from database but for time being I have hard coded few values.
$rootScope.populate = function () {
$rootScope.models = {
MyModel: {}
};
$rootScope.models.MyModel.Client = [];
$rootScope.models.MyModel.Client.FirstName = 'FName';
$rootScope.models.MyModel.Client.LastName = 'LName';
$rootScope.TempVars = [
{"key":"var-FirstName","value":"{{models.MyModel.Client.FirstName}}"},
{ "key": "var-LastName", "value": "{{models.MyModel.Client.LastName}}" },
]
};
Following is my HTML code
<input type="hidden" ng-repeat="obj in TempVars" name="{{obj.key}}" value="{{obj.value}}" />
<input type="text" ng-repeat="obj in TempVars" name="{{obj.key}}" value="{{obj.value}}" />
<input type="hidden" name="test" value="{{models.MyModel.Client.FirstName}}" />
I am expecting that hidden filed value should have FName and LName in it. But rather it contains {{models.MyModel.Client.FirstName}} and {{models.MyModel.Client.LastName}} in it. Whereas variable name with name test has FName value stored in it.
Is is possible to achieve this in angularjs?
It won't work that way in angularjs but you will be able to do that through a custom directive and using NGModelController to $format and $parse the data.
Here are some links where you can get the idea about that :
https://egghead.io/lessons/angularjs-using-ngmodel-in-custom-directives
http://radify.io/blog/understanding-ngmodelcontroller-by-example-part-1/

ng-model - getting name and value of input box

I have an update function and a number of input boxes. Each input has an ng-blur attached to it so that the update function is called whenever the cursor leaves the box.
$scope.update = function(data) {
console.log(data); //outputs value in the textbox
//how can I output/access the key?
}
The input for name look like this:
<input type="text" ng-model="user.name" ng-blur="update(user.name)"/>
As I need to be able to post a JSON object in the form {"name" : "bob smith"} what's a good way of generating the "key" of the object bearing in mind that it will differ depending on the input box that's being used at the time?
EDIT ↓
I have made this jsfiddle to illustrate a way to do it more cleanly & that would scale more easily: http://jsfiddle.net/kuzyn/k5bh0fq4/5/
EDIT ↑
Why not simply pass a second string argument? It's not a fancy way to do it but it would work:
<input type="text" ng-model="user.name" ng-blur="update(user.name, 'name')"/>
And
$scope.update = function(data, key) {
console.log(key, data);
}
It might be a little more work but it is much more scalable. You could make use of the ng-form and naming your form inputs. By naming your form and inputs, you are creating a form reference on your scope via $scope[form-name]. Each named input within that form then sets an input reference via $scope[form-name][input-name].
I'm coding this in coffeescript (to preserve my sanity, sorry)
form
<form name="myForm">
<input name="name" ng-model="user.name" ng-blur="update(user)"/>
<input name="email" ng-model="user.email" ng-blur="update(user)"/>
<input name="other" ng-model="user.other" ng-blur="update(user)"/>
</form>
update & save func
# key is what changed in case you need to do something special on the put call to server
$scope.save = (data, key)->
# pseudo-code
$scope.update = (data)->
for name, input of $scope.myForm
if input?.$dirty
$scope.save data, name
break
docs - https://docs.angularjs.org/guide/forms
codepen - http://codepen.io/jusopi/pen/LGpVGM?editors=101

How do you show validation errors returned from WebAPI?

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;
}

How get AngularJS element by name?

In my form validation there is part of server validations.
So I should get back from the server list with the names of the fields and a string with the error in each of them.
My idea was to write a general code knowledge to deal with all fields without knowing them in advance, by accessing them with their name.
this is field for example:
<!-- Email -->
<div class="form-group" data-ng-class="{ 'has-error' : step1Form.email.$invalid && (!step1Form.email.$pristine || submitted) }">
<label>Email</label>
<input type="email" name="email" class="form-control" data-ng-model="user.email" required data-ng-minlength="5" data-ng-maxlength="60">
<p data-ng-show="step1Form.email.$error.required && (!step1Form.email.$pristine || submitted)" class="help-block">required!</p>
<p data-ng-show="step1Form.email.$error.minlength" class="help-block">too short1</p>
<p data-ng-show="step1Form.email.$error.maxlength" class="help-block">too long!</p>
<p data-ng-show="step1Form.email.$error.email" class="help-block">invalid email!</p>
<p data-ng-show="step1Form.email.$error.serverError" class="help-block">{{emailServerError}}</p>
</div>
like you can see, the variable emailServerError is saved for errors that come from the server validations...
i have a lot fields in my application and i try to write generic code that will fit for all the fields...
so this is the angular code:
// function to submit the form after all validation has occurred
$scope.submitForm = function() {
// check to make sure the form is completely valid
if ($scope.step1Form.$valid) {
// now we will go to server side validation
// AJAX calls.......
// lets say we got this back:
var problem = { field: 'email', msg: 'this email is already registered'};
// now we need to setValidity for email input.
var errorVariableName = $parse(problem.field + 'ServerError'); // Get the name of the error string variable.
errorVariableName.assign($scope, problem.msg); // Assigns a value to it
console.log($scope.emailServerError); // = 'this email is already registered'
// HERE THE PROBLEM:
// now i need to do something like that:
// $scope.step1Form. + problem.field + .$setValidity('serverError', false);
// but i dont know how to this that.
// i think that i need to get this element ($scope.step1Form. + problem.field) in some way by name, and then use setValidity on it. but i dont know how..
}
};
the question is in the comments inside the code...
You can try
$scope.step1Form
and then access the right value with
$scope.step1Form["nameOfProblemfield"]

Resources