1

I have the following div

<div class="form-group col-lg-12 ignore-left-padding" ng-show="!labeledIntents">
  <label for="intent-count"><h4>Number of intents</h4></label>
     <div>
        <switcher ng-model="manualNumberOfIntents"
                  ng-change="onSwitcherChange()" 
                  false-label="Autodetect" true-label="Manual input">
        </switcher>&nbsp;
        <input ng-if="manualNumberOfIntents" show-focus="autoNumberOfIntents"
               ng-model="$parent.count" type="number" step="1" min="1" 
               max="200" id="intent-count" placeholder="1-200"
               style="width: 75px;" required/>
    </div>
</div>

In there i have a switch which, when turned on, displays a number box that is mandatory. For this text box I set it such that it appears when "manualNumberOfIntents" is enabled. After that the user is needed to enter a number in it or an error message pops up. once everything is set, the user presses a submit button which creates a project of some sort using the information provided.

Here is part of the function which is called when submit is pressed:

$scope.submit = function (event) {
    event.preventDefault();
    if (!$scope.file) {
      return;
    }
    $scope.projectNameDuplication = false;
    $scope.requestInProgress = true;
    var projectname = $scope.projectname.trim();
    var userparticipant = $scope.customChatParticipants ? $scope.userparticipant : "USER";
    var agentparticipant = $scope.customChatParticipants ? $scope.agentparticipant : "AGENT";
    var count = $scope.manualNumberOfIntents ? $scope.count : false;
    console.log($scope.count);

It then uses the variables and processes them.

Here is the function which gets called when the switch is activated:

$scope.onSwitcherChange = function () {
    $scope.count = '';
  }

In the code above console.log returns nothing no matter what i tried to set for count. Which brings me to believe that count is just set to '' via $scope.onSwitchChange but never touched again. I did some research and found that ng-if creates its own scope and so if i use ng-model="count" it would not work since it is trying to reference count in a scope that the parent cannot access. Thus I put ng-model="$parent.count". However this still does not seem to work... does anyone have any ideas?

When i modify $scope.count, it does so under the parent scope so it should not affect the way i reference it in the html right? Any suggestions would be greatly appreciated! I am quite new at angularjs so i apologize in advance if this is an obvious question.

georgeawg
  • 48,608
  • 13
  • 72
  • 95
Ted
  • 365
  • 1
  • 7
  • 16

1 Answers1

1

I put ng-model="$parent.count". However this still does not seem to work

Using $parent will only work if there is only one level scope hierarchy between the model and the controller. It will not work for multiple levels of heirarchy.

The solution is to use a property of an object on the controller scope:

$scope.form1 = { count: 0 };

$scope.submit = function (event) { 
     console.log($scope.form1.count);
};
<input ng-if="manualNumberOfIntents" show-focus="autoNumberOfIntents"
       ng-model="form1.count" type="number" step="1" min="1" 
       max="200" id="intent-count" placeholder="1-200"
       style="width: 75px;" required/>

For more information, see


so what exactly is $parent.count accessing in this case? would this be accessing the count value in the highest point of the hierarchy?

$parent.count accesses the count property of the parent scope.

$parent.$parent.count accesses the grandfather scope.

$parent.$parent.$parent.count accesses the great-grandfather scope.

New AngularJS developers often do not realize that ng-repeat, ng-switch, ng-view, ng-include and ng-if all create new child scopes, so the data hiding problem often shows up when these directives are involved.1

While prefixing one or more $parent identifiers may work, it is not a robust solution as changes to the HTML may add or remove layers of hierachy which in turn will break the solution. The more robust solution is to define objects in the parent for your model, then reference a property of that object in the child: parentObj.someProp.

For more information, see

georgeawg
  • 48,608
  • 13
  • 72
  • 95
  • Thanks so much, that worked. Followup question though, so what exactly is $parent.count accessing in this case? would this be accessing the count value in the highest point of the hierarchy? – Ted Nov 01 '19 at 13:02