I have an app with a bunch of tabs. When a tab is selected, the corresponding section of body becomes visible by a reactive change to a HTML class. When this happens, I want to focus() a text input box. However, because the section of body was display: none, and because you can’t call focus on something that has display:none set, there is no right time for me to call focus().
The successful workaround is to put a setTimeout for 50ms in the code that makes the change to the session variable to cause the reactive change, but obviously that’s not the right way to do anything.
I think this is essentially what Tracker.afterFlush is designed for. Just put your focus code in the afterFlush callback, and the DOM should have updated by the time it runs (provided the relevant computation has actually been invalidated when you call afterFlush).
I wrote the originally SO question, thanks xaxxon for following it up on here
The manual Tracker.Flush forces the updates and triggers re-rendering of the UI that is affected but I’m not sure if what is within the defer block could still be called too early?
Another example where you want to initialize a plugin when the subscription is done:
Template.listing.onRendered(function () {
var template = this;
template.subscribe('listOfThings', function () {
// Wait for the data to load using the callback
Tracker.afterFlush(function () {
// Use Tracker.afterFlush to wait for the UI to re-render
// then use highlight.js to highlight a code snippet
highlightBlock(template.find('.code'));
});
});
});