I have a Chart component which has ‘canvas’ as tagName property. I want to change tagName when there is not data to render the chart (I would avoid to render the chart). The docs say that I should destroy and create a new element view. I’m trying to do that on willInsertElement event and in fact, it destroys the view, but then it’s not created again using the new tagName:
willInsertElement: function() {
var _this = this;
Ember.RSVP.Promise.resolve(this.get('data')).then(function(data){
if (!data) {
_this.set('tagName', 'div');
_this.destroyElement();
_this.createElement();
}
});
},
What is the proper way to do this? Is there another place where I should put this instead of willInsertElement?
The problem is that data is a Controller’s property processing a promise that won’t be resolved at the time of inserting the element into the DOM. So, I think that if statement will always be true.
// controllers/my-controller.js
userData: function(){
return this.get('userStatistics').then(function(data) {
// prepare data for chart
return dataForChart;
});
}.property('userStatistics');
It seems to me that this would create a perpetual loop, no?
-> willInsertElement
-> wait for promise to resolve
-> destroy element
-> createElement
-> willInsertElement
-> wait for promise
-> already resolved so then is called immediately
-> destroy element
-> create element
(repeat)
EDIT
I believe you also need to return that promise and the call to _this.createElement.
Furthermore, if this.get('data') is a promise, you don’t need to wrap it in a promise that always resolves.
This uses a private property, but if you simply want to display the notice until the promise has resolved or rejected (e.g. ember-chart handles rejection) then RSVP Promises have a _state property which is null initially, 1 on resolve, and 2 on reject.