Bind JSON object to radio button in angularjs

All we need is an easy explanation of the problem, so here it is.

So I am trying to bind radio buttons to objects. I have spent like an hour trying to figure this up and at last admit defeat. Here’s what I got:

<table>
        <tr ng-repeat="theCustomer in customers">
            <td>
                <input type="radio" ng-model="currentCustomer" value="theCustomer" id="{{theCustomer.id}}" ng-change="currentCustomer = theCustomer">
                <label for="{{theCustomer.id}}">{{theCustomer.name}}</label>
            </td>
        </tr>
</table>

The angular stuff:

bankApp.controller("BankController", function ($scope, CustomerRepository)
{
    $scope.customers = [];
    $scope.currentCustomer = {};
    
    $scope.createCustomer = function () {
        CustomerRepository.save($scope.customer, function (customer) {
            $scope.customers.push(customer);
            $scope.customer = {};
        });
    };
});

Currently, when I try and click on a radio button nothing happens, it doesn’t even get checked. I’m sure there’s got to be a really simple solution to this. The end goal is to have currentCustomer hold the customer reflected in the radio selection.

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

<input type="radio" ng-model="$parent.currentCustomer" name="foo" ng-value="theCustomer" id="{{theCustomer.id}}">{{theCustomer.name}}</td>

The key here is the ng-value="theCustomer. This is how angular knows which object is selected. The html value only knows string values and cannot map to objects.

If you insert the above code, the radio will reflect the model, even if it is changed programatically. Also, you can’t forget the $parent in the ng-model because the ng-repeat creates a new scope.

Method 2

Apparently, getting a radio group to work inside an ng-repeat can be a bit tricky. The issue is with the ng-repeat creating its own child scope. One solution is to bind the model to the $parent. This thread gives an example.

I also created a working fiddle that more closely resembles your example.

In essence, I think your html is the only point that needs reworking:

<table>
  <tr ng-repeat="theCustomer in customers">
    <td><input type="radio" ng-model="$parent.currentCustomer" name="foo" value="{{theCustomer}}" id="{{theCustomer.id}}">{{theCustomer.name}}</td>
  </tr>
</table>

Method 3

It is because of the scope inheritance, you can read more about the problem here.

One solution that I use in such a case, is to bind the object to an object property instead of a primitive value like ng-model="form.currentCustomer".

Demo: Plunker

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply