14

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.

3 Answers 3

22
<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.

Sign up to request clarification or add additional context in comments.

Comments

5

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>

5 Comments

So this works mostly, the only problem is currentCustomer is being set as stringified json rather than the object. Is there an easy fix for this? I tried doing it without the double braces and that didnt work.
What do you wish the final result to look like exactly?
I actually figured it out. The value attribute only takes a string and cant handle an object. I refactored to accommodate this. Thanks!
@CodesLikeA_Mokey Can you post the refactored code? How are you able to set the default selected radio button? jsfiddle.net/uNFWW/31
@Tushar see me answer below.
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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.