Error appending Pagedown in AngularJS Directive
Asked Answered
T

2

1

Based on this question, though I felt this warranted its own question: Google pagedown AngularJS directive

Following the example from this question, it seems to work, however I am running into issues when I try to append a directive to the page.

Here is the code I have in the linking function:

  scope.editor_id = null;

  if(attrs.id == null) {
    scope.editor_id = nextID++;
  } else {
    scope.editor_id = attrs.id;
  }

  //append editor HTML
  //has to be done here so that it is available to the editor when it is run below
  var editor_html = $compile(
      '<div id="wmd-button-bar-' + scope.editor_id + '"></div>' +
      '<textarea class="wmd-input" id="wmd-input-' + scope.editor_id + '" ng-model="content"></textarea>'
  )(scope);


  element.find('.wmd-panel').append(editor_html);


  var editor = new Markdown.Editor(editor_converter, "-" + scope.editor_id);
  editor.run();

However, when I append one of these to the document, I get the following error:

TypeError: Cannot read property 'attachEvent' of null

This error tends to crop up when the wmd-input is not present in the HTML. however, I am adding it with the $compile function, and it works on page load, but not when it is appended. What am I doing wrong here?

Thibodeaux answered 27/1, 2014 at 17:41 Comment(0)
W
4

UPDATE

I was able to reproduce your problem: http://plnkr.co/edit/R2eDKBreHmYBjPtU0JxD?p=preview

Why typeError: Cannot read property 'attachEvent' of null?

  • I was wrong with my previous assumption ( the composite linking function do returns the element)
  • The problem is with the way you use angular.element#find.
  • angular.element#find only search for child elements not on the whole document.
  • the DOM element with a .wmd-panel class is not a child of the current element.

This should work fine:

angular.element('.wmd-panel').append(editor_html);
Windpollinated answered 27/1, 2014 at 18:7 Comment(2)
I'd like only to note that you need to be careful when adding node not to the child element - if the directive's parent node/scope will be destroyed (with ng-if or by routing) this editor_html will not and will keep the link to the directive's scope. That may lead to memory leaks.Pasteurism
@Pasteurism you are correct. I only answered the OP why the error occurs and how to fix it. It also feels "non angular" to use selectors on the document like that. I bet there is more angular way to achieve what he needs but the question doesn't provide much details.Windpollinated
S
0

Try doing compile like this:

$compile('template stuff goes here')(scope, function(cloned, scope){
   element.append(cloned); 
});

You may also have to define your editor inside the callback function because I'm not sure if it's asynchronous or not. You may also want to re-consider having your directive compile and append to itself like this. Why not just add more instances of the entire directive using something like ng-repeat?

Also, if you have multiple instances inside this one directive, you will lose reference to editor. Not sure what's going on outside this code so I can't really tell.

Stephenstephenie answered 27/1, 2014 at 18:0 Comment(1)
The linking function is not asyncWindpollinated

© 2022 - 2024 — McMap. All rights reserved.