When working with AngularJS (version 1.x), a common requirement is to bind a form input to a property of a filtered object within an array. While AngularJS provides powerful filtering mechanisms using filter, using that directly inside the ng-model can be tricky — especially if you’re trying to bind a specific property of the filtered result.

In this blog, we’ll walk through:

  • Why this is a challenge
  • A common misunderstanding
  • A working solution with explanation

The Problem: Binding ng-model to a Filtered Property

Let’s say you have the following data structure in your AngularJS controller:

function MyCtrl($scope) {
  $scope.results = {
    year: 2013,
    subjects: [
      { title: 'English', grade: 'A' },
      { title: 'Maths', grade: 'A' },
      { title: 'Science', grade: 'B' },
      { title: 'Geography', grade: 'C' }
    ]
  };
}
<p data-source-line="26" class="empty-line final-line end-of-document" style="margin:0;"></p>

We want the user to:

  • Edit the year (simple binding)
  • Edit the title of the subject that has grade C (filtered binding)

A naive approach in HTML might look like:



But this won’t work.

Why Doesn’t This Work?

The AngularJS filter expression returns a new array, and ng-model expects an object property, not a filtered result. Angular cannot bind ng-model to a derived value like that because it has no idea where to write changes back to.

The Correct Approach

To bind the input to the title of the subject with grade ‘C’, you need to:

  1. Filter the subject manually in the controller or with a custom function.
  2. Assign the filtered subject to a scope variable.
  3. Bind ng-model to that variable’s title property.

Solution Example



  
    
    
    AngularJS Filter + ng-model
  
  
    

Edit Year:

Edit Title of Subject with Grade 'C':

angular.module('myApp', []) .controller('MyCtrl', function($scope) { $scope.results = { year: 2013, subjects: [ { title: 'English', grade: 'A' }, { title: 'Maths', grade: 'A' }, { title: 'Science', grade: 'B' }, { title: 'Geography', grade: 'C' } ] }; // Find subject with grade C $scope.subjectWithGradeC = $scope.results.subjects.filter(function(subject) { return subject.grade === 'C'; })[0]; });

Now, any updates to the second input will directly update the title of the subject with grade ‘C’.

Why This Works

  • ng-model=”subjectWithGradeC.title” is a valid reference to a model.
  • The object reference subjectWithGradeC is resolved once in the controller and maintained in $scope.
  • AngularJS tracks subjectWithGradeC.title like any other normal binding — no filtering at runtime needed.

Dynamic Grade Selection (Bonus)

If you want to let users choose the grade and dynamically bind to that subject’s title, use $watch:




$scope.selectedGrade = 'C';

$scope.$watch('selectedGrade', function(newVal) {
  $scope.filteredSubject = $scope.results.subjects.find(function(subject) {
    return subject.grade === newVal;
  });
});

Conclusion

In AngularJS 1.x:

  • Avoid using | filter directly in ng-model.
  • Instead, filter data in the controller or via ng-repeat/$watch.
  • Always bind ng-model to a real object property reference.

This keeps your code both editable and bindable, which is critical when building forms and data-driven UIs in AngularJS.

Need Help With Angular Development?

Work with our skilled Angular developers to accelerate your project and boost its performance.

Hire Angular Developers

Support On Demand!

Related Q&A