How do I re-render a template in meteor, after calling a method, in an event?

625 views
Skip to first unread message

Gage Bachik

unread,
Dec 15, 2014, 2:02:47 AM12/15/14
to meteo...@googlegroups.com

In my rendered function a change some html on the page like so:

$($($('.round'+nextRound).find('li')[nextMatch]).find('.participant')[currentParticipant]).find('a').addClass('tooltip').html(winnerBox);

I need to undo that change in one of my event handlers aka:

'click #swear': function(event){
    Meteor.call('submitWinner', winnerInfo, thisCampaign._id, Meteor.user().apiKey, function(error, result) {
        // display the error to the user and abort
        if (error){
            return alert(error.reason);
        }else{
          !RE-RENDER MY TEMPLATE HERE!
          // Session.set('roundUpdated', true);
        }
    });
},

I've tried using session variables ect but am having absolutely no luck! I think the problem is that this one template has 3 nested each blocks:

each round
  ul(class='round#{currentRound} of#{rounds}')
    each match
      li
       each participant

The helpers look like this:

round: function() {
    // Session.set('updated', (Session.get('updated')+1));
    var tournament = this.tournament.brackets;
    var rounds = tournament.length;
    var results = [];
    tournament.map(function(value, index){
        var currentRound = index + 1;
        results.push({rounds: rounds, currentRound: currentRound, matches: value});
    });
    // console.log("results:", results);
    return results;
},
match: function(){
    // console.log("matches:", this.matches);
    return this.matches;
},
participant: function(){
  // do some calculations here
  return results;
},

The code is a little incomplete for brevity, but hopefully you can get the idea! The weirdest part is that if I put a log in the participant helper it logs the correct thing but it never get rendered back into the html... like it still has what I forced in with jquery.

If I update the template from another client then it works? like two separate clients update correctly but one does not.

Any ideas of what's going on or what I can do to fix it?

steph643

unread,
Dec 15, 2014, 6:09:34 AM12/15/14
to meteo...@googlegroups.com
From what I understand, this is the expected behavior.
Meteor will only update a part of the DOM if this part has changed since the last Meteor rendering operation. Because Meteor has no way to get informed of what you did with jQuery, nothing is updated.
There are several solution to your problem. The advised one is to forget about jQuery and implement the addClass('tooltip').html(winnerBoxusing Meteor.

mr zafod

unread,
Dec 15, 2014, 6:11:10 AM12/15/14
to meteo...@googlegroups.com
Hi, I guess than Blaze doesn't update your template correctly becaise of using jquery in rendered callback. Why don't you render your winnerBox or add classes via Blaze's rendering?

each round
    ul
(class='round#{currentRound} of#{rounds}')
            each match
                li each participant
                        if tooltipFor this._id
                            a
.tooltip(href='#')
                               
<your winnerBox tooltip html here>






понедельник, 15 декабря 2014 г., 13:02:47 UTC+6 пользователь Gage Bachik написал:

Gage Bachik

unread,
Dec 15, 2014, 5:33:49 PM12/15/14
to meteo...@googlegroups.com
So the reason I can't do that is because it relies on older information given to me by ther rendered participants.

the entire function looks like this:

Meteor.defer(function(){
/* start round counter */
if (Session.get('roundEndTime')) {
roundEndTime();
}
var bracketCount = 0;
var canSubmit = true;
var shouldSubmit = true;
var participants = $('.participant-id');
var pending = $('.participant-pending');
var currentParticipant;
var nextRound;
var thisMatch;
var nextMatch;
var bracket;

console.log("pending.length:", pending.length);

if (pending.length > 0) { 
pending.map(function (index, value) {
var disagree = $(value).parent().find('.participant-disagree').text();
var checkId = $(value).parent().find('.participant-id').text();
console.log("Meteor.userId(), disagree, checkId:", Meteor.userId(), disagree, checkId);
if (Meteor.userId() === checkId || Meteor.userId() === disagree) {
// console.log("can NOT FUCKING Submit:");
canSubmit = false;
}
});
}

if (canSubmit) {
participants.map(function(index, value){
if ($(value).text() === Meteor.userId()) {
if ($(value).parent().find('.participant-status').text() === 'undetermined') {
nextRound = $(value).parent().find('.participant-round').text();
thisMatch = $(value).parent().find('.participant-match').text();
bracket = $(value).parent().parent().parent().find('.participant');
bracketCount++;
};
};
});
if (bracket) {
bracket.map(function (index, participant) {
if ($(participant).find('.participant-status').text() != 'undetermined') {
shouldSubmit = false;
}
});
if (bracketCount > 1) {
shouldSubmit = false;
}
}
if (Session.get('submittedWinner')) {
shouldSubmit = false;
Session.set('submittedWinner', false);
}
console.log("shouldSubmit:", shouldSubmit, canSubmit);
if (shouldSubmit) {
nextRound = parseInt(nextRound) + 1;
nextMatch = Math.round(parseInt(thisMatch)/2) - 1;
if (parseInt(thisMatch) % 2 != 0) {
currentParticipant = 0;
}else{
currentParticipant = 1;
}
var winnerOptions = '';
var winnerBox = $('<div class="select-winner">');

if (bracket) {
bracket.map(function(index, value) {
if ($(value).find('.participant-title').text().trim() != '' && $(value).find('.participant-title').text().trim().toLowerCase() != 'bye') {
winnerOptions += '<span class="winner-option"> '+$(value).find('.participant-title').text()+' <div class="winner-info"> '+$(value).find('a').html()+' </div> </span>';
};
});
winnerBox.append(winnerOptions);
$($($('.round'+nextRound).find('li')[nextMatch]).find('.participant')[currentParticipant]).removeClass('loser').addClass('undetermined');
$($($('.round'+nextRound).find('li')[nextMatch]).find('.participant')[currentParticipant]).find('a').addClass('tooltip').html(winnerBox);
}
}
}

});


steph643

unread,
Dec 16, 2014, 3:40:21 AM12/16/14
to meteo...@googlegroups.com
Well, I don't know enough about what you want to achieve. However, looking at your code, it seems that:
- you are doing heavy DOM manipulation using jQuery,
- you are storing data in the DOM to get it back later.

What you might want to do instead:
- Generate your DOM using Meteor markup in your html ({{...}})
- Store your data in reactive data sources such as Collections (server+client) or Session (client only)

Gage Bachik

unread,
Dec 16, 2014, 4:06:47 AM12/16/14
to meteo...@googlegroups.com
Thanks for all the replies guys! I was able to finally get it working!

My best guess is If you replace a templates html with jquery it messes up the DOM and can no longer render correctly or at all for that matter even though their helper function is called.

I was able to circumvent this by adding a condition to the helper that will do half of what I had written (replace the html) and then I only ever end up replacing the html once instead of twice.

That's kind of confusing to explain and it would be better to just rewrite it all correctly but I'm already 1k lines of code in and it would take an extensive re-write to do so.

Anyways feel free to message me if you run into this issue.

-Thanks
Reply all
Reply to author
Forward
0 new messages