[FIX] sale: ensure widget is alive before executing code
Steps to reproduce the bug: - Add a delay (for example 5 seconds) at the beginning of the `/sale/get_combination_info_website` route. - Add a delay (for example 10 seconds) in a `willStart` method in the `Wysiwyg`. - Go on a product page and enter edit mode. - Click on the the product image. -> The "Replace" button does not appear. In this situation, the added delays represent slow rpc answers. Let's analyse the flow of instructions in order to better understand the problem: - When you go on a product page, the `WebsiteSale` public widget is started. `_getCombinationInfo` of `VariantMixin` is then called through the `start()` of the public widget. As the rpc is taking time to answer, `_onChangeCombination()` is not directly called. - When entering edit mode, the `WebsiteSale` public widget is destroyed. Due to the edit mode, the `o_editable` class has been added on editable elements. - After the first added delay and thanks to the rpc answer, `_updateProductImage()` is called through `_onChangeCombination()`. Because the `editor_enable` class has not been added to the document body yet (due to the second added rpc), the `_updateProductImage()` method replaces some elements of the DOM and by doing so, removes the `o_editable` class of some elements. Consequently, the snippet option linked to the image is not displayed. The problem here is that the `_updateProductImage` method is called even if its associated public widget has been destroyed. To solve the problem, we first check that the associated widget is alive before handling the result of the rpc answer in the `VariantMixin` mixin. Note that the first idea was to use `this._rpc()` instead of `ajax.jsonRpc()` in the mixin. Indeed, the advantage of using `this._rpc()` is that it already ensures that the associated widget is alive before handling the result of the rpc answer. The problem is that some widgets that use the `VariantMixin` are created in such a way that `this._rpc()` can not be used on them (for example `OptionalProductsModal`). Related to runbot-28700 closes odoo/odoo#149145 X-original-commit: 599e112ba7580617c61226b73355035c89af3395 Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com>
This commit is contained in:
@@ -79,6 +79,9 @@ var VariantMixin = {
|
||||
'context': this.context,
|
||||
...this._getOptionalCombinationInfoParam($currentOptionalProduct),
|
||||
}).then((combinationData) => {
|
||||
if (this._shouldIgnoreRpcResult()) {
|
||||
return;
|
||||
}
|
||||
this._onChangeCombination(ev, $currentOptionalProduct, combinationData);
|
||||
this._checkExclusions($currentOptionalProduct, childCombination, combinationData.parent_exclusions);
|
||||
});
|
||||
@@ -98,6 +101,9 @@ var VariantMixin = {
|
||||
'context': this.context,
|
||||
...this._getOptionalCombinationInfoParam($parent),
|
||||
}).then((combinationData) => {
|
||||
if (this._shouldIgnoreRpcResult()) {
|
||||
return;
|
||||
}
|
||||
this._onChangeCombination(ev, $parent, combinationData);
|
||||
this._checkExclusions($parent, combination, combinationData.parent_exclusions);
|
||||
});
|
||||
@@ -721,6 +727,18 @@ var VariantMixin = {
|
||||
.addClass("active");
|
||||
},
|
||||
|
||||
/**
|
||||
* Return true if the current object has been destroyed.
|
||||
* This function has been added as a fix to know if the result of a rpc
|
||||
* should be handled. Indeed, "this._rpc()" can not be used as it is not
|
||||
* supported by some elements that use this mixin.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_shouldIgnoreRpcResult() {
|
||||
return (typeof this.isDestroyed === "function" && this.isDestroyed());
|
||||
},
|
||||
|
||||
/**
|
||||
* Extension point for website_sale
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user