Search code examples
javascriptangularjsangular-formly

How to reference form field created by AngularJS formly


I use Formly for creating my forms in angularJS

This is my field

$scope.postFields = [
    {
        key: 'title',
        type: 'input',
        templateOptions: {
            label: "Title",
            // required: true,
            minlength: 2,
        },
        validation: {
            messages: {
                required: function(viewValue, modelValue, scope) {
                    return scope.to.label + ' is required'
                }
            }
        }
    }
]

and I'm trying to access my fields as follows

    function failure(response) {
    console.log("failure", response)

    _.each(response.data, function(errors, key) {
        _.each(errors, function(e) {
            $scope.form[key].$dirty = true;
            $scope.form[key].$setValidity(e, false);
        });
    });
}

my formly form

<formly-form form="postForm" model="model" fields="postFields" class="col-md-4">
    <button type="submit" class="btn btn-primary" ng-click="addPost()">Submit</button>
</formly-form>

but of course I'm getting this error:

TypeError: Cannot read property 'title' of undefined

it's on this line

$scope.form[key].$dirty = true;

do anyone of you know how to reference created formly fields the right way?


Solution

  • If you want to be able to reference the fields from the form, you could provide a name attribute to your fields. The name is generated by default. It's one of the nice things that angular-formly provides (you don't have to think about it). But if you want to reference it directly with a specific key (as you are) then you'd be best served by providing one yourself.

    So you'd do something like this:

    $scope.postFields = [
        {
            key: 'title',
            name: 'title',
            type: 'input',
            templateOptions: {
                label: "Title",
                // required: true,
                minlength: 2,
            },
            validation: {
                messages: {
                    required: function(viewValue, modelValue, scope) {
                        return scope.to.label + ' is required'
                    }
                }
            }
        }
    ]
    

    Alternatively, you could create a fieldTransform to do this automatically (just assign the name the same as the key). Or in your error handler, you could look up the NgModelController from the field's formControl property like this:

    function handleError(fields, response) {
      _.each(fields, function(field) {
        if (response.data[field.key]) {
          field.formControl.$setDirty()
          _.each(response.data[field.key], function(e) {
            field.formControl.$setValidity(e, false)
          })
        }
      })
    }
    

    That's probably the best solution :-) Good luck!