2

Here is the html:

<select style="width: 100%;" ng-model="vm.orgType" ng-model-options="{getterSetter: true}" ng-options="orgType as orgType.ORGANIZATION_TYPE for orgType in vm.orgTypes">
                                </select>

and here is the getter/setter function:

function orgType(selectedType) {
            if (arguments.length == 0)
                return orgType.selectedOrgType || { ORGANIZATION_TYPE: 'Organization Type', ORGANIZATION_TYPE_ID: null };

            orgType.selectedOrgType = selectedType;
            if (selectedType.ORGANIZATION_TYPE_ID) {
                if (vm.registrant.StakeholderOrgs[0])
                    vm.registrant.StakeholderOrgs[0] = selectedType.ORGANIZATION_TYPE_ID;
                else
                    vm.registrant.StakeholderOrgs.push(selectedType.ORGANIZATION_TYPE_ID);
            }
            else
                vm.registrant.StakeholderOrgs.splice(0);
        }

the following line:

return orgType.selectedOrgType || { ORGANIZATION_TYPE: 'Organization Type', ORGANIZATION_TYPE_ID: null };

throws the infinite digest loop error.

Let me explain what I am trying to do here. I need to push the id onto a list if there is a selection made. I realize that I could just do an ng-model on some variable selectedOrgType and then just put my logic in an ng-change. However, I am trying to make a dropdown that does not create any unnecessary model variables. Instead, I was hoping to just put the logic in a getter/setter, that seems more appropriate to me. One of vm.orgTypes is { ORGANIZATION_TYPE: 'Organization Type', ORGANIZATION_TYPE_ID: null }, I was hoping that would be my default value instead I get this digest error, don't understand where it is coming from.

2
  • watch in this case check equals by reference, and if you return { ORGANIZATION_TYPE: 'Organization Type', ORGANIZATION_TYPE_ID: null } you every check return new object. If you have same object in collection - just use it like return orgType.selectedOrgType || vm.orgTypes[0]. Or just save in variable: var defVal = { ORGANIZATION_TYPE: 'Organization Type', ORGANIZATION_TYPE_ID: null } and use return orgType.selectedOrgType || defVal Commented Oct 22, 2015 at 18:45
  • @Grundy Want to add an answer? Commented Oct 22, 2015 at 19:37

1 Answer 1

3

When you add ng-model attribute, angular add internal watch, that check value on every digest loop, and if value changed - run digest again.

In you case you return object literal. In javascript when you compare two literals, even with same structure - you get false

({a:1} == {a:1}) // false

because this really two different object.

So, when you return object literal in your getter, watch check it with previous value, and, as i say above, if you return literal - get false

So you get your error with infinite digest.

For solving you just need return same object.

If you have this object inside array, like

vm.orgTypes=[
    { ORGANIZATION_TYPE: 'Organization Type', ORGANIZATION_TYPE_ID: null }
];

So you just need use it directly:

 return orgType.selectedOrgType || orgTypes[0];

Yer another way: just save default falue to varible and use it

var defaultSelect = { ORGANIZATION_TYPE: 'Organization Type', ORGANIZATION_TYPE_ID: null };

....

function orgType(selectedType) {
    if (arguments.length == 0)
        return orgType.selectedOrgType || defaultSelect;

In this case you would return same element in default case, so avoid infinite digest loot.

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

4 Comments

I'm trying to normalize an input. The input can be input[type=text] or it can be a <select>. I'm always returning an object litereal -- I need to. How would you get around this? Your Answer wasn't really a solution -- you just said don't do that.
@Cody, possibly you not see code after For solving you just need return same object. Anyway, you can ask your own question, because problem can be somewhere else
I saw the return same object line -- which works like a charm, if you can return the same object. I my case, it may not even be an option. Thx for the input though.
@Cody, without your code, i can't suggest how apply my answer to your issue :)

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.