0

I have got an angular controller that calls a resource and then puts the result in to a variable.

Then in my HTML I am loping through the objects in that variable and rendering some HTML elements using ng-repeat.

The problem I'm having is, for each of the HTML elements being rendered I need to call a function which involves, getting the element by it's id.

At the point when I call this JS function, the elements have not been rendered yet.

This is the controller code.

cmsUserResource.GetOpCoUsersViewModel($routeParams.id.split("-")[1]).then(
  function (response) {

    vm.response = response;

    //This works because the HTML for this element is not generated dynamically
    Sortable.create(document.getElementById('advanced-1'), {
      sort: true,
      group: sortableOptions,
      animation: 200,
      onStart: function () {
        angular.element(document.getElementById('opCoUsersForm')).scope().opCoUsersForm.$dirty = true;
      }

    });


    vm.response.brands.forEach(function (brand) {
      //This DOES NOT work, the elements are not on the page yet.

      Sortable.create(document.getElementById('brand-' + brand.id), {
        sort: true,
        group: sortableOptions,
        animation: 200,
        onStart: function () {
          angular.element(document.getElementById('opCoUsersForm')).scope().opCoUsersForm.$dirty = true;
        }

      });
    });
  });

This is the HTML code

<div class="block__list">
  <div>
    <div class="formDefinitionPositionTitle">CMS Users in {{vm.response.opCo.companyName}} </div>
    <ul id="advanced-1" class="block__list_tags handle">
      <li umbracoUserId="{{cmsUser.cmsUserId}}" ng-repeat="cmsUser in vm.response.cmsUsers">{{cmsUser.cmsUserName}}</li>
    </ul>
  </div>
</div>

<h3>Users In Brands</h3>
<div ng-repeat="brand in vm.response.brands">
  <div class="block__list">
    <div>
      <div class="formDefinitionPositionTitle">CMS Users in {{brand.brandName}} </div>
      <ul id="brand-{{brand.id}}" class="block__list_tags handle">
        <li umbracoUserId="{{cmsUser.cmsUserId}}" ng-repeat="cmsUser in brand.cmsUsers">{{cmsUser.cmsUserName}}</li>
      </ul>
    </div>
  </div>
  <br /><br />
</div>

So how do I force angular to wait for the HTML before calling the:

Sortable.create(document.getElementById('brand-' + brand.id),
spencer.sm
  • 19,173
  • 10
  • 77
  • 88
Ayo Adesina
  • 2,231
  • 3
  • 37
  • 71

1 Answers1

0

You need to look at the lifecycle hooks (https://angular.io/guide/lifecycle-hooks) of AngularJS.

With Angular, you would use AfterViewInit, which would allow you to execute some code "after the component's view has been fully initialized".

So you need to find the equivalent for AngularJS, which would be the hook $postLink() from this documentation : https://docs.angularjs.org/guide/component

br.julien
  • 3,420
  • 2
  • 23
  • 44