AngularJS form and null / empty values

I work with a somewhat dynamic form of AngularJS. In other words, I can add lines of input fields, etc. So my approach was to start with an empty $scope.formData in order to encapsulate all the properties bound to both static and dynamic elements of the HTML form.

AngularJS code is as follows:

 (function() { var formApp = angular.module("formApp", []); formApp.controller("FormCtrl", function ($scope, $timeout) { $scope.formData = {}; $scope.formData.subscribers = [ { name: null, email: null } ]; $scope.addSubscriber = function() { $scope.formData.subscribers.push({ name: null, email: null }); }; }); })(); 

HTML for AngularJS form:

 <body data-ng-app="formApp"> <div data-ng-controller="FormCtrl"> <p> Name of Topic: <input type="text" data-ng-model="formData.title" placeholder="enter a title" /> </p> Subscribers: <button data-ng-click="addSubscriber()">Add subscriber</button> <table> <tr> <th>Name</th> <th>Email</th> </tr> <tr data-ng-repeat="subscriber in formData.subscribers"> <td><input type="text" data-ng-model="subscriber.name" placeholder="enter name" /></td> <td><input type="text" data-ng-model="subscriber.email" placeholder="enter email" /></td> </tr> </table> <hr style="margin:1em 0;" /> <p> <em>Debug info</em>: {{ formData }} </p> </div> </body> 

Notice the debugging information section at the end that displays the $scope.formData object and its contents. I have a couple of problems with how I implemented this form.

  • When the first page loads, $scope does not have the formData.title property, but since it is bound to the header text box, when I start typing in the value, the title property is added to $scope . However, when I delete the value in the input text field, the formData.title property still exists in $scope as an empty string. I suppose this is normal, but I really want to clear empty or null values ​​when submitting the form. I would like to do this on the client side if this is easy to do, so server-side code should not take anything away.
  • In the dynamic subscribers section, I can add as many rows as I want, but ultimately, I would like to filter out all empty client objects on the client side.

Does AngularJS have any options for detecting and clearing null / empty values ​​in $scope before further processing, for example, $http POST?

Note I set jsFiddle for this example.

+7
javascript html angularjs angularjs-scope
source share
4 answers

I try to avoid using observers for performance reasons. With that said, this is really not so much an Angular question as a JavaScript question. Since you have full control over when data is transferred to the service, I would just clear it first. This is pretty simple, since your data structure is so small.

https://jsfiddle.net/1ua6oj5e/9/

 (function() { var formApp = angular.module("formApp", []); formApp.controller("FormCtrl", function ($scope, $timeout) { // Remove junkiness var _remove = function remove(item) { if ($scope.formData.title === undefined || $scope.formData.title === '') { delete $scope.formData.title; } }; $scope.formData = {}; $scope.formData.subscribers = [ { name: null, email: null } ]; $scope.addSubscriber = function() { $scope.formData.subscribers.push({ name: null, email: null }); }; // Submit to test functionality $scope.submit = function() { // Remove title if empty _remove($scope.formData.title); /* Remove name and email if empty. * If your list of fields starts to get large you could always * just nest another iterator to clean things up. */ angular.forEach($scope.formData.subscribers, function(sub) { _remove(sub.name); _remove(sub.email); }); }; }); })(); 
+2
source share
 function replacer(key, value) { if (value == "" || value == null) { return undefined; } return value; } var foo = {foundation: "", model: {year: 2015, price:null}, week: 45, transport: "car", month: 7}; foo = JSON.stringify(foo, replacer); foo =JSON.parse(foo); console.log(foo); 
+2
source share

Just use ngModelController $ parsers and overwrite the default HTML input element.

With this implementation, you can constantly monitor the value of the model. Thus, in your case, you can set the model to null when the view value is empty. Line.

 var inputDefinition = function () { return { restrict: 'E', require: '?ngModel', link: function (scope, element, attr, ngModel) { if (ngModel) { var convertToModel = function (value) { return value === '' ? null : value; }; ngModel.$parsers.push(convertToModel); } } }; /** * Overwrite default input element. */ formApp.directive('input', inputDefinition); 

Here is the updated JSFiddle: https://jsfiddle.net/9sjra07q/

+2
source share

Added by Watcher to formData,

 $scope.$watch('formData',function(n,o){ if(typeof $scope.formData.title !== 'undefined' && $scope.formData.title === "" ){ delete $scope.formData.title; } },true); 

Updated script: https://jsfiddle.net/1ua6oj5e/6/

For all dynamic fields you should use angular form validation, you should see this: https://docs.angularjs.org/guide/forms

+1
source share

All Articles