2

I am calling a $http get method and in the success callback, the response that I get, based on that response, in the html, am doing an ng-repeat to iterate over the elements. Also, am maintaining the ids of some divs dynamically based on the $index of the ng-repeat. Now, when I am trying to set the innerHTML of these divs based on their ids, it is giving me an error, as that element has not been created at that time. Am confused regarding what is happening in this case. A mock code snippet below for your reference:

<tr ng-repeat-start= "dataArray in gridData" >
    <td>
        <span ng-bind="expanded ? '-' : '+'" ng-click="expanded = !expanded"></span>{{dataArray.name}}
    </td>
    <td>
        <div id="th_{{$index + 1}}" ng-hide="expanded" ng-repeat="rcL1 in rch.rcs" >
            <div ng-hide="expandedTreeCol" id="to_{{$parent.$index}}_{{$index}}">
            </div>
        </div>
    </td>
</tr>

and here is the js snippet:

$http.get(url)
        .then(function(response) {
            console.log(response);

            $scope.gridData = response.data.data;

            var rch = $scope.rch.rcs;
            var grid_data = $scope.gridData;

            document.getElementById("to_0_0").innerHTML = "1";
        });

while trying to set this innerHTML, it says 'Cannot set property 'innerHTML' of null. However, when i complete the execution of my code, in the dom, i can find the div with that id created. However, it seems it is not yet created when i am in the callback function. Someone please explain what is happening here and how can i set the innerHTML from the js.

Thanks.

Ori
  • 55
  • 1
  • 1
  • 9
  • Avoid doing DOM manipulation like `document.getElementById("to_0_0").innerHTML = "1";` in controllers. Use `{{ }}` to bind model to contents of a div. – georgeawg Aug 13 '18 at 11:25
  • actually, i tried with the {{}} binding initially but the requirement includes a lot of calculations to be made and then display the results in each . I got stuck in between and had to resort to this way, which i agree i do not like too. Anyway, probably will try to rack my head on the {{}} approach once more. thanks. – Ori Aug 13 '18 at 12:28
  • If you are having problems with a robust approach, you should ask us about that. Asking us to fix a flakey approach is not a productive use of our time. And it leaves a bad example that will be copied. – georgeawg Aug 13 '18 at 12:34
  • I did not ask to fix this approach primarily. I wanted to understand what is going on here and why the element is not rendered in the callback block. Maybe you misunderstood. However, now I understand that the ng-repeat is not completing its rendering while the control is in the callback function. I am searching more on this. If you however, can provide me any pointers to understand how ng-repeat, $http and $digest works internally, then it will be very helpful. Thanks. – Ori Aug 13 '18 at 12:54

1 Answers1

-1
  1. ng-repeat directive initialize and init watcher on $scope.rch.rcs
  2. send http request, execute callback
  3. document.getElementById("to_0_0") return nothing
  4. As you use $http, it triggers $digest
  5. $digest runs -> watcher on $scope.rch.rcs see changes -> ng-repeat directive renders elements
Petr Averyanov
  • 9,327
  • 3
  • 20
  • 38
  • Okay. So, from what I understood, the ng-repeat rendering is not yet completed when i am trying to access the element with its element id. So, ideally i should find a way to execute my code after the ng-repeat rendering is completed.. hmmmm... – Ori Aug 13 '18 at 12:25