Blaze.render() error : where parentNode is not a DOM element


#1

Hello,

I got a event for my template :

'click .addPlayer': function() {
    return Blaze.render(Template.teamPlayerDefinition, document.getElementsByClassName('playerData'), document.getElementsByClassName('addPlayer'), Template.newTeamDefinition);
} 

But I can’t insert the template because the console tell me :

Error: 'parentElement' must be a DOM node

In the official documentation of Meteor, there is no code example of a good Blaze.render().

Can somebody help me ?

The template if hase follow :

<div id="playerCoachData">
  <div class="clearfix playerData">
    <div class="playerDefinition clearfix">{{>teamPlayerDefinition}}</div>
    <button class="btn btn-primary addPlayer shadow" type='button'>{{_ "addPlayer"}}</button>
  </div>
  <div class="clearfix">
    <div class="coachDefinition clearfix">{{>teamCoachDefinition}}</div>
    <button class="btn btn-primary addCoach shadow" type='button'>{{_ "addCoach"}}</button>
  </div>
</div>

#2

It should work. Have you checked that document.getElementsByClassName('playerData') returns the correct DOM node?

As side notes:

  • you might consider using jQuery, as it is included in Meteor
  • you can narrow your DOM search by looking in the template only
    Putting this together:
'click .addPlayer': function(event, template) {
  Blaze.render(
    Template.teamPlayerDefinition, 
    template.$('.playerData').get(0),
    template.$('.addPlayer').get(0),
    Template.newTeamDefinition
  );
}

#3

Just by a quick peek, I would say getElementsByClassName returns an array of DOM elements
so make sure you refer a DOM element and not an array


#4

I’ll check tonight to replace class by ID or via .get(0).

I can’t use JQuery because the code won’t allow it : https://github.com/meteor/meteor/blob/master/packages/blaze/view.js#L599

// parentElement must be a DOM node. in particular, can't be the
// result of a call to `$`. Can't check if `parentElement instanceof
// Node` since 'Node' is undefined in IE8.
if (parentElement && typeof parentElement.nodeType !== 'number')
    throw new Error("'parentElement' must be a DOM node");

#5

you can use the instance.find('.some-class') method
it returns the first matching DOM element within the template instance (not a jQuery object)

also, there’s no restriction on using jQuery for extracting the DOM element:

$('.some-class')[0]

#6

Hence the .get(0), to convert from a jQuery object to a node object.


#7
'click .addPlayer': function(event, template) {
   var playerDataElement, addPlayerElement;
   if (playerDataElement = template.find('.playerData') && addPlayerElement = template.find('.addPlayer') {
      Blaze.render(
         Template.teamPlayerDefinition, 
         playerDataElement,
         addPlayerElement,
         Template.newTeamDefinition);
      }
}

#8

Hello,

Thank you all for your help, mostly @mrzafod. I made it work like this :

Template :

<div class="clearfix playerData">
  {{>teamPlayerDefinition}}
</div>
<button class="btn btn-primary clearfix shadow addPlayer" type='button'>{{_ "addPlayer"}}</button>

Event :

'click .addPlayer': function(e, t) {
    return Blaze.render(Template.teamPlayerDefinition, t.$('.playerData').get(0));
}