I'm using the jQuery DataTables plugin to render data in Ember. I'm running into classic race condition issues and some part of my understanding of Ember and the Ember run-loop must be incomplete. Here's what's happening.
- I output a table of data in my Template, using
<table>...<tbody>{{#each user in model}}...
- In my View, I call the DataTables library in the
didInsertElement
method, and wrap it inEmber.run.scheduleOnce('afterRender', function() { $('#myTable').DataTable(); })
- The first time I access this page code, I get the following error:
Uncaught Error: Cannot perform operations on a Metamorph that is not in the DOM.
- If I access it again, it works fine.
I have looked at similar StackOverflow posts on this:
- Ember.js - "Cannot perform operations on a Metamorph that is not in the DOM" caused by template
- ember js with datatables plugin
But these fixes don't seem to work. I suspect that DataTables is trying to update the DOM before Ember has finished rendering it, but then why doesn't my called Ember.run.scheduleOnce('afterRender', ...)
address that?
Strangely, I can get it work by doing the following:
Old (Race Condition) Code in View:
didInsertElement: function() {
Ember.run.scheduleOnce('afterRender', function() {
$('#orgUsers').DataTable();
});
}
New Working Code in View:
didInsertElement: function() {
setTimeout(function() {
$('#orgUsers').DataTable();
}, 0);
}
Note that I have specified a javascript setTimeout
delay of 0 seconds! But this works every time.
Can someone help me understand (1) why does wrapping this in setTimeout()
solve all my problems, (2) what is the "Ember Way" to handle this? Thanks!
DataTable
, but it makes sense. I have found that Ember is powerful enough to let me do lots of things I used to use libraries for... I roll my own tables, personally. – Steve H.