didInsert called with null node.el when mount() is followed by immediate redraw()
See original GitHub issueHi,
I’m seeing didInsert being called twice - once with the node and once without. So you can effectively ignore the faulty one (it IS faulty and a bug, right?) by simply doing “if (!node) return”
I have an Dashboard view with Chart views. The chart views have didInsert hooks that are called twice.
Something like this:
var insert_counter = 1 // didInsert counter - is called 6 times
var nodes_counter = 1 // didInsert with valid node's - called 3 times
function Chart (vm, opts) {
function didInsert (node) {
console.log("counter: " + insert_counter++)
if (!node) return
console.log("valid nodes counter: " + nodes_counter++)
}
return ['div.chart',
['canvas', {_hooks: {didInsert: didInsert}}]
]
}
function Dashboard (vm, store) {
return function () {
['div.dashboard',
['div', [Chart, opts]],
['div', [Chart, opts]],
['div', [Chart, opts]]
]
}
}
Issue Analytics
- State:
- Created 7 years ago
- Comments:22 (10 by maintainers)
Top Results From Across the Web
The Component Lifecycle - Ember Guides
Ember guarantees that, by the time didInsertElement() is called: The component's element has been both created and inserted into the DOM.
Read more >ember_guides_combined - gists · GitHub
Welcome to Ember.js! This guide will take you through creating a simple application using Ember.js and briefly explain the core concepts behind the...
Read more >Scenekit move node - Caritas Castellaneta
SceneKit itself uses a scene-graph model, in which nodes are positioned ... Jun 27, 2018 · The didAdd() is called whenever a new...
Read more >The domvm from domvm - GithubHelp
Rendering a view to the DOM is called mounting. ... You can access any view's parent view via vm.parent() and the great granddaddy...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Nor am I. I was just hoping to shed more light on the general problem in case it was helpful. It does not affect me, since I am already deferring and coalescing redraws, and any user of DOMVM can do the same in a few lines of code. But, just in case more things like this come out of the woodwork, I thought this might be useful information.
So turns out this is a bit of a thorny issue. Here are some details.
vm.redraw
is debounced/coalesced so if you call it 20 times within the samerequestAnimationFrame
, it will only fire the last invocation on the tail end of the frame. In addition,did*
hook firing is delayed by 1-2 frames to ensure that the created DOM elements are “live” and are useful to you.What’s happening here is that the queue is filled with the callbacks and current nodes/args via the implicit
redraw()
as part ofmount()
, but thedid*
hooks don’t fire until the next frame. If you call anotherredraw()
before the queue is drained, those nodes in the queue become stale because they are regenerated on each redraw and theel
transferred/recycled to the new vnodes. So when the hooks do fire, you’re getting stale nodes that should be garbage collected.What I’m gonna do is have domvm queue any
redraw()
calls if thedidHooks
queue is non-empty to prevent node replacement/recycling prior to hook invocation. Since thedidHooks
queue (and nowpendRedraws
queue) is global and cannot really be contained to a specific view, the solution is not a general one and may cause odd interactions in cases of significant complexity or asynchronicity WRT implicit sub-sub-subview redraw containing deepdid*
hooks cases. But it should cover multiple common cases such as explicit view redraw like the one here.