I have this implementation:
instance.web_calendar.CalendarView.include({
handle_special_dates: function(date, cell){
var def = $.Deferred(),
model = new instance.web.Model('calendar.special');
model.call('get_special_dates').then(function(result){
// Transform date strings into date obj valueOf result.
var new_obj = {}
for (key in result){
if (result.hasOwnProperty(key)){
var dt_value = new Date(key).valueOf();
// Set new key as date.ValueOf() and use
// special date name as value.
new_obj[dt_value] = result[key]
}
}
return new_obj;
}).then(function(result){
// We stringify value, because object stringifies keys
// automatically.
var dt_value = String(date.valueOf())
// Check if date value is in special dates keys.
// We check for -1, because it actually returns index,
// not a boolean value.
if ($.inArray(dt_value, Object.keys(result)) != -1){
var div = $(
'<div />',
{
"class": 'fc-special-day',
text: result[dt_value]
}
)
cell.children('div').prepend(div)
// Set special day background
cell.addClass('fc-special-background')
}
})
return def;
},
get_fc_init_options: function(){
var self = this;
fc_options = this._super()
if (this.special_dates){
return $.extend({}, fc_options, {
dayRender: function(date, cell){
self.handle_special_dates(date, cell)
}
});
} else {
return fc_options;
}
},
})
}
handle_special_dates
function call method that is defined in backend of the system (this is asynchronous call), parses the result and uses it to check if we need to modify cell
of the calendar.
The problem is that both then
parts are called as many times as there are cells to check. So this is kind of clunky, because I need to call backend only once and then use result for all the cells.
Basically first then
(the one that calls get_special_dates
backend method) part should be called only once. I tried to separate that functionality, but then it is called later than dayRender
needs it. In other words, it will never call when it is needed:).
Is there some way to somehow wait for first part to finish instead of calling it like it is now? I mean it is asynchronous call, but now I guess it is even slower than synchronous.
P.S. I know there is new Promise
functionality in JS, but Odoo in this version currently uses jQuery deferred, so I'm using it too.
Update
To better explain the situation, I will try to describe the structure, what is currently done, and what the problem is.
This system has two parts, backend (managed by Python) and frontend (Javascript).
Backend manages data that can be used by frontend. To be specific, there is a method in backend called get_special_dates
. It returns dates with names entered in specific table called calendar_special
. So if someone enters any such date, it will return its date string representation (and name). For example we can enter date 2017-04-16
and call it Easter
.
Now when Javascript part loads the calendar interface, it checks all currently visible calendar dates and compares with dates returned by get_special_dates
. If compared dates match, it will mark them in calendar.
But the problem is, get_special_dates
is now called as many times as there are checks for each date/cell pair. Let say if we have 30 dates in month and we are seeing 30 dates of that month, it would call get_special_dates
30 times, when in reality only one call is enough (because dates from backend are same for all date/cell pair checks). But I need to save result to be reused for all date/cell pairs (or some other way that is proper for deferred
).
Basically it checks every visible calendar date and compares with what was entered in backend.
Maybe this picture makes more sense how this functionality work. Dates with green background are actually dates that were entered in backend as special dates.