5

I've got a problem with a form. I'm submitting the form and some of the fields don't have to be filled, when the data is send to a restful API I see that angular doesn't pick up the empty, never touched, never changed, input fields. But on the server side the field is expected to be present. How can I get angular to send these fields as well?

I have two inputs (data.Record.one, data.Record.two), when I fill one and submit the form I'm ending up with this:

{
  "Record": {
    "one": "test"
  }
}

I guess this is because angular doesn't "see" untouched and empty fields. But I want that:

{
  "Record": {
    "one": "test",
    "two": ""
  }
}

Here is a demo of what I try: http://plnkr.co/edit/Ky0PQ9U5o1V7IyU9QgkK

I'm well aware that I could initialize the form with an empty skeleton object but I would really prefer to not have to do that. If I need to do that it's just additional code that as a bonus will just introduce an area of potential fail if another dev adds a field in the form but forgets / doesn't know about the skeleton in the JS code.

4
  • 1
    next time try to write code in question Commented Jun 3, 2014 at 7:31
  • SO doesn't like it if you paste huge chunks of code and not much text beside that: "Looks like you post mostly code". And Angular examples are often longer because of all the JS and HTML needed to demo it... Commented Jun 3, 2014 at 8:04
  • Just so i understand. You want AngularJS to automaticly initialize your Record object with empty strings for all properties that you have mapped to an input field? Commented Jun 3, 2014 at 8:41
  • Yes, exactly that. :) Commented Jun 3, 2014 at 19:50

4 Answers 4

2

Angular treats empty fields as empty/null by default. You can disable this by adding ng-trim="false" on your input fields.

This will not add extra code, only definition on your markup.

https://docs.angularjs.org/api/ng/input/input%5Btext%5D

EDIT: I see now what you want. Angular takes good care of your model (data). Just because you bind an input field to a sub,sub property won't initialize the property with empty string. The input fields does not contain empty string - they contain null which is what you put in them in the first place (by binding them to an uninitalized property).

The feature you want, is for angular to initialize your data.Record with the properties you need. You could make a custom directive for that called initialize-property that would set its model to an empty string.

EDIT: I created the directive but plunker won't let me access due to some cross domain problems. You should be able to use it in your own work though

myApp.directive('initializeProperty', function() {
  return {
      restrict: 'A',
      link: function (scope, element, attr) {
        element.val('');
      }
  };
});

And then on your input fields use this:

One <input name="one" ng-model="data.Record.one" initialize-property ng-trim="false" /><br />
Two <input name="one" ng-model="data.Record.two" initialize-property ng-trim="false" /><br />
Sign up to request clarification or add additional context in comments.

1 Comment

Busy right now with something else, I'll try it later.
1

replace your app.js code to this one

var myApp = angular.module('myApp', []);

myApp.controller('TestFormController', ['$scope', '$log', function($scope, $log) {
    $scope.data = {
      Record : {
        "one": "",
      "two": ""
      }
    }
    $scope.add = function() {
        $log.log($scope.data);
    }
}]);

DEMO

UPDATE ! change your view with this html

One <input name="one" ng-init="data.Record.one = ''" ng-model="data.Record.one"  /><br /> 
Two <input name="one" ng-init="data.Record.two = ''" ng-model="data.Record.two" /><br />

i have added extra ng-init directive which will initilize your data

DEMO

2 Comments

But I would like to avoid that I have to initialize the form with an "empty" template object.
@Falk i have update my answer (update 1), hope this will solve your problem
1

I fixed it simply using ng-init="inputfieldname=''"

Comments

0

I had the same problem, so then in my research I find this: http://blog.fernandomantoan.com/angularjs-forcando-bind-de-todos-os-campos-no-submit/

Solve my problem, but I had to edit, thus:

.directive('forceBind',  function() {
    return {
        require: '^form',
        priority: -1,
        link: function (scope, element, attrs, form) {
            element.bind('submit', function() {
                angular.forEach(form, function(value, key) {  
                    if(typeof value == 'object'){
                        if (value.hasOwnProperty('$modelValue')) {
                            if (!value.$viewValue) {
                                value.$setViewValue("");
                            }
                        }
                    }
                });
            });
        }
    };
});

So, when the event submit runs, before entering in method the directive force bind. I recommend using ng-submit for validation. Sorry my english.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.