2

Using AngularJS I need to append HTML to the elements of ng-repeat, using the selector: 'objectMapParent-' + post._id

  <div ng-repeat="post in posts">

    <div id="{{ 'objectMapParent-' + post._id }}">
      <h5 style="color:blue; margin-top: 3px;">{{post.title}}</h5>

    </div>
  </div>

so I created a loop to loop through the elements of the posts array, where for each element I call the function: createElement

 $scope.posts = [{
    _id: "1",
    title: "map of london"
  }, {
    _id: "2",
    title: "map of brazil"
  }, {
    _id: "3",
    title: "map of usa"
  }];

  $scope.posts.forEach(function(post) {
    // console.log(post);

    createElement("#objectMapParent-" + post._id, function() {
      //create map here after append 
    });
  });

This callback function gets a selector, elementParent, which we use to find the node in the DOM, and then apend the desired HTML

  var createElement = function(elementParent, cb) {

    var aux = elementParent;

    var postId = aux.replace("#objectMapParent-", "");

    var myElement = angular.element(document.querySelector(elementParent));

    var html = "<div id='objectMap-" + postId + "'><div id='BasemapToggle-" + postId + "'></div></div>";
    myElement.append(html);

    cb();
  };

But something does not work, as far as I'm concerned, the document.querySelector function can not find the selector.

It seems to me that when it tries to select, the node does not yet exist in the DOM.

I reproduced the code in the codepen, it might help.

georgeawg
  • 48,608
  • 13
  • 72
  • 95
krekto
  • 1,403
  • 14
  • 18
  • Not sure I understand why you're not building this structure directly from the view, is it because you need to create that map after the append? Because you can use the `ngInit` directive and call that function from the view – Alon Eitan Apr 28 '19 at 22:50
  • Why you're trying to do it manually? What's the problem in angularjs template? – Rannie Aguilar Peralta Apr 28 '19 at 22:53
  • @AlonEitan I can not use document.querySelector for an ng-repeat item. I do not understand why. This is very important for my project. – krekto Apr 29 '19 at 01:46
  • 1
    Avoid doing DOM manipulation in controllers. Instead add DOM using [custom directives](https://docs.angularjs.org/guide/directive). This is especially true when working with the `ng-repeat` directive which adds and destroys DOM in the course of its operation. The querySelector can't find the element because the `ng-repeat` directive hasn't added it yet. – georgeawg Apr 29 '19 at 03:35

1 Answers1

2

How to Encapsulate jQuery code in a Custom Directive

Any jQuery code that manipulates the DOM should be encapsulated in a custom directive so that it is executed when the AngularJS framework ng-repeat directive instantiates the element.

<div ng-repeat="post in posts">
    <div id="{{ 'objectMapParent-' + post._id }}">
         <h5 style="color:blue; margin-top: 3px;">{{post.title}}</h5>
         <my-element post="post"></my-element>
    </div>
</div>
app.directive("myElement", function() {
    return {
        link: postLink,
    };
    function postLink(scope,elem,attrs) {
        var post = scope.$eval(attrs.post);
        var html = `
          <div id="objectMap-${post._id}">
            <div id="BasemapToggle-${post._id}">
            </div>
          </div>
        `;
        elem.append(html);
    }
})

To use jQuery, simply ensure it is loaded before the angular.js file.

For more information, see

Community
  • 1
  • 1
georgeawg
  • 48,608
  • 13
  • 72
  • 95
  • @ georgeawg You are absolutely correct, however I am adding dojo widgets that are giving error when I add them ng-repeat, I wanted to try giving the append of these widgets by the controller. Thank you – krekto Apr 29 '19 at 03:29