SlideShare a Scribd company logo
Asynchronous JS in Odoo
Vincent Schippefilt • JS Framework developer
It will be fine, It’s a new Promise()
2019
EXPERIENCE
Promises
Create a promise
Wait for a promise
Handle errors
*Handle errors in Odoo
Wait for multiple promises
Wait until first resolved
new Promise(function(resolve, reject) { ...
myPromise.then(function(result) { ...
const result = await myPromise;
myPromise.catch(function(error) { ...
try { await myPromise; } catch(error) { ...
myPromise.guardedCatch(function(e) { ...
Promise.all([prom1, prom2])
Promise.race([prom1, prom2])
Promises
● Asynchronous function
● Public function (API)
○ returns a promise
Code: tiny.cc/async-1
Step by
Step
  
Code: tiny.cc/async-2
Wait for the Promise
  
Code: tiny.cc/async-2
Load a template
Code: tiny.cc/async-3
Load a template - fix
Code: tiny.cc/async-4
Create and instanciate Widget
1. Define MyWidget
2. Instanciate it
odoo.define('new_widget', function(require) 
{
    var Widget = require('web.Widget');
    var MyWidget = Widget.extend({
        template: "my_template"
    });
    var x  = new MyWidget();
    x.appendTo($('#somewhere'));
});
Code: tiny.cc/async-5
Create and instanciate - Fix
1. Define MyWidget
2. Instanciate it in an action
odoo.define('new_widget', function (require) {
    // require...
    var MyWidget = Widget.extend({
        template: "my_template"
    });
    var MyAction = AbstractAction.extend({
        start: function () {
            var myWidgetInstance = new MyWidget();
            var prom = myWidgetInstance.appendTo ($('#somewhere'))
            return Promise.all([
                prom,
                this._super.apply(this, arguments)
            ])
        }
    });
    core.action_registry.add('my_action', MyAction);
});
Code: tiny.cc/async-6
More complex problems
Master details Widget
1. Define Widget
2. On click row  showDetails
3. showDetails  RPC then render
4. On click button (in detail) 
navigateTo (in a modal)
odoo.define('master_detail_widget', function (require) {
    // require ...
    return Widget.extend({
        template: 'master_detail_template',
        events: {
            'click tr': 'showDetails',
            'click button.navigateTo': 'navigateTo'
        },
        async showDetails(ev) {
            this.id = ev.target.dataset.id;
            this.data = await this._rpc({/*...*/ id: this.id});
            this.render();
        },
        navigateTo(ev) {
            this.do_action('open_record_details',
                {
                    recordId: this.id,
                    target: 'new'
                });
        }
    });
});
The Code
Code: tiny.cc/async-7
What happens if a
user clicks on a
row, then
showDetails right
after?
odoo.define('master_detail_widget', function (require) {
    // require ...
    return Widget.extend({
        template: 'master_detail_template',
        events: {
            'click tr': 'showDetails',
            'click button.navigateTo': 'navigateTo'
        },
        async showDetails(ev) {
            this.id = ev.target.dataset.id;
            this.data = await this._rpc({/*...*/ id: this.id});
            this.render();
        },
        navigateTo(ev) {
            this.do_action('open_record_details',
                {
                    recordId: this.id,
                    target: 'new'
                });
        }
    });
});
Question
Code: tiny.cc/async-7
Issue: when the user clicks fast
on navigateTo just after
selecting a row, he is shown
with the details of the
previously selected row
Fix: set the id of the selected row
after the rpc
odoo.define('master_detail_widget', function (require) {
    // require ...
    return Widget.extend({
        template: 'master_detail_template',
        events: {
            'click tr': 'showDetails',
            'click button.navigateTo': 'navigateTo'
        },
        async showDetails(ev) {
            var id = ev.target.dataset.id;
            this.data = await this._rpc({/*...*/ id: id});
            this.id = id;
            this.render();
        },
        navigateTo() {
            this.do_action('open_record_details',
                {
                    recordId: this.id,
                    target: 'new'
                });
        }
    });
});
[FIX] fast click
Code: tiny.cc/async-8
when the user clicks fast on
different rows
Issue 1: he has to wait a long time
to see the last one he
selected
Issue 2: the details do not always
arrive in order
Other issues
odoo.define('master_detail_widget', function (require) {
    // require ...
    return Widget.extend({
        template: 'master_detail_template',
        events: {
            'click tr': 'showDetails',
            'click button.navigateTo': 'navigateTo'
        },
        async showDetails(ev) {
            var id = ev.target.dataset.id;
            this.data = await this._rpc({/*...*/ id: id});
            this.id = id;
            this.render();
        },
        navigateTo() {
            this.do_action('open_record_details',
                {
                    recordId: this.id,
                    target: 'new'
                });
        }
    });
});
odoo.define('master_detail_widget', function (require) {
    // require ...
    return Widget.extend({
        template: 'master_detail_template',
        events: {
            'click tr': 'showDetails',
            'click button.navigateTo': 'navigateTo'
        },
        async showDetails(ev) {
            var id = ev.target.dataset.id;
            this.data = await this._rpc({/*...*/ id: id});
            this.id = id;
            this.render();
        },
        navigateTo() {
            this.do_action('open_record_details',
                {
                    recordId: this.id,
                    target: 'new'
                });
        }
    });
});
Code:
● Show last ASAP
● Show all in sequence
You need to decide
Show last ASAP
Concurrency.DropPrevious
Click
#3
Loaded #3
Click #43 Loaded #43
Click
#3
Loaded #3
Click #99 Loaded #99
#99 Shown
Implement DropPrevious
odoo.define('master_detail_widget', function (require) {
    // require ...
    var concurrency = require('web.concurrency');
    return Widget.extend({
        // ...
        init: function () {
            this.detailDP = new concurrency.DropPrevious();
        },
        showDetails: function (ev) {
            var id = ev.target.dataset.id;
            await this.detailDP.add(this._rpc(this,{/*...*/ id: id }));
            this.id = id;
            this.render();
        },
        navigateTo() {
            // ...
        }
    });
});
odoo.define('master_detail_widget', function (require) {
    // require ...
    var concurrency = require('web.concurrency');
    return Widget.extend({
        // ...
        init: function () {
            this.detailDP = new concurrency.DropPrevious();
        },
        showDetails: function (ev) {
            var id = ev.target.dataset.id;
            await this.detailDP.add(this._rpc(this,{/*...*/ id: id }));
            this.id = id;
            this.render();
        },
        navigateTo() {
            // ...
        }
    });
});
Code: tiny.cc/async-8
Show all in sequence
Concurrency.Mutex
Click
#3
Click #43
Click #43
Click #3 Loaded #3
#3 Shown
Loaded #43 #43 Shown
Loaded #43 #43 Shown
Loaded #3 #3 Shown
Implement Mutex
odoo.define('master_detail_widget', function (require) {
    // require ...
    var concurrency = require('web.concurrency');
    return Widget.extend({
        // ...
        init: function () {
            this.loadDetailsMutex = new concurrency.Mutex();
        },
        showDetails: function (ev) {
            var id = ev.target.dataset.id;
            var loadData = this._rpc.bind(this,{/*...*/ id: id });
            await this.loadDetailsMutex.exec(loadData);
            this.id = id;
            this.render();
        },
        navigateTo() {
            // ...
        }
    });
});
odoo.define('master_detail_widget', function (require) {
    // require ...
    var concurrency = require('web.concurrency');
    return Widget.extend({
        // ...
        init: function () {
            this.loadDetailsMutex = new concurrency.Mutex();
        },
        showDetails: function (ev) {
            var id = ev.target.dataset.id;
            var loadData = this._rpc.bind(this,{/*...*/ id: id });
            await this.loadDetailsMutex.exec(loadData);
            this.id = id;
            this.render();
        },
        navigateTo() {
            // ...
        }
    });
});
Code: tiny.cc/async-9
More Odoo Primitives
/web/static/src/js/core/
concurrency.js
1. Do not execute if not ordered
2. Execute one after the other
3. Execute last as fast as possible
4. Execute first, last, wait for
completed
5. Wait X milliseconds
1. const dm = new DropMisordered(); 
dm.add(promise)  Promise;
2. const m = new Mutex();
m.exec(function)  Promise;
3. const dp = new DropPrevious();
dp.add(promise)  Promise;
4. const mdp = new MutexedDropPrevious();
mdp.exec(function)  Promise
5. delay(_ms)  Promise
● Know what returns a Promise
● Wait for promises
● Async is hard, use concurrency.js
primitives
To remember
Thank you.
#odooexperience
2018
2019
EXPERIENCE

More Related Content

PPTX
Owl: The New Odoo UI Framework
PPTX
Developing New Widgets for your Views in Owl
PDF
ES6 presentation
PPTX
Tutorial: Develop an App with the Odoo Framework
PDF
Svelte JS introduction
PDF
TypeScript Best Practices
PPTX
Boxing & unboxing
PPT
JavaScript & Dom Manipulation
Owl: The New Odoo UI Framework
Developing New Widgets for your Views in Owl
ES6 presentation
Tutorial: Develop an App with the Odoo Framework
Svelte JS introduction
TypeScript Best Practices
Boxing & unboxing
JavaScript & Dom Manipulation

What's hot (20)

PPTX
AngularJS Directives
PDF
Odoo - Create themes for website
PPSX
Php and MySQL
PDF
엘라스틱서치 실무 가이드_202204.pdf
PPT
JavaScript
PPTX
An Intro into webpack
PDF
RESTful API 설계
PDF
PPT
Oops in PHP
PPTX
Introduction to java 8 stream api
PDF
react redux.pdf
ODP
Angular 4 The new Http Client Module
PPT
jQuery Ajax
PDF
Tips on how to improve the performance of your custom modules for high volume...
PPT
PDF
Django Introduction & Tutorial
PDF
Angular Directives
PPTX
Angular Data Binding
PDF
REST APIs with Spring
PDF
NodeJS for Beginner
AngularJS Directives
Odoo - Create themes for website
Php and MySQL
엘라스틱서치 실무 가이드_202204.pdf
JavaScript
An Intro into webpack
RESTful API 설계
Oops in PHP
Introduction to java 8 stream api
react redux.pdf
Angular 4 The new Http Client Module
jQuery Ajax
Tips on how to improve the performance of your custom modules for high volume...
Django Introduction & Tutorial
Angular Directives
Angular Data Binding
REST APIs with Spring
NodeJS for Beginner
Ad

More from Odoo (20)

PPTX
Timesheet Workshop: The Timesheet App People Love!
PPTX
Odoo 3D Product View with Google Model-Viewer
PPTX
Keynote - Vision & Strategy
PPTX
Opening Keynote - Unveilling Odoo 14
PDF
Extending Odoo with a Comprehensive Budgeting and Forecasting Capability
PDF
Managing Multi-channel Selling with Odoo
PPTX
Product Configurator: Advanced Use Case
PDF
Accounting Automation: How Much Money We Saved and How?
PPTX
Rock Your Logistics with Advanced Operations
PPTX
Transition from a cost to a flow-centric organization
PDF
Synchronization: The Supply Chain Response to Overcome the Crisis
PPTX
Running a University with Odoo
PPTX
Down Payments on Purchase Orders in Odoo
PPTX
Odoo Implementation in Phases - Success Story of a Retail Chain 3Sach food
PPTX
Migration from Salesforce to Odoo
PPTX
Preventing User Mistakes by Using Machine Learning
PPTX
Becoming an Odoo Expert: How to Prepare for the Certification
PPTX
Instant Printing of any Odoo Report or Shipping Label
PPTX
How Odoo helped an Organization Grow 3 Fold
PPTX
From Shopify to Odoo
Timesheet Workshop: The Timesheet App People Love!
Odoo 3D Product View with Google Model-Viewer
Keynote - Vision & Strategy
Opening Keynote - Unveilling Odoo 14
Extending Odoo with a Comprehensive Budgeting and Forecasting Capability
Managing Multi-channel Selling with Odoo
Product Configurator: Advanced Use Case
Accounting Automation: How Much Money We Saved and How?
Rock Your Logistics with Advanced Operations
Transition from a cost to a flow-centric organization
Synchronization: The Supply Chain Response to Overcome the Crisis
Running a University with Odoo
Down Payments on Purchase Orders in Odoo
Odoo Implementation in Phases - Success Story of a Retail Chain 3Sach food
Migration from Salesforce to Odoo
Preventing User Mistakes by Using Machine Learning
Becoming an Odoo Expert: How to Prepare for the Certification
Instant Printing of any Odoo Report or Shipping Label
How Odoo helped an Organization Grow 3 Fold
From Shopify to Odoo
Ad

Recently uploaded (20)

PDF
Roadmap Map-digital Banking feature MB,IB,AB
PPTX
Dragon_Fruit_Cultivation_in Nepal ppt.pptx
PPTX
3. HISTORICAL PERSPECTIVE UNIIT 3^..pptx
PDF
Deliverable file - Regulatory guideline analysis.pdf
PDF
Stem Cell Market Report | Trends, Growth & Forecast 2025-2034
PDF
Katrina Stoneking: Shaking Up the Alcohol Beverage Industry
PDF
NewBase 12 August 2025 Energy News issue - 1812 by Khaled Al Awadi_compresse...
PPTX
svnfcksanfskjcsnvvjknsnvsdscnsncxasxa saccacxsax
PPTX
Probability Distribution, binomial distribution, poisson distribution
PPTX
HR Introduction Slide (1).pptx on hr intro
PDF
Elevate Cleaning Efficiency Using Tallfly Hair Remover Roller Factory Expertise
PDF
Power and position in leadershipDOC-20250808-WA0011..pdf
PPTX
Amazon (Business Studies) management studies
PPTX
Lecture (1)-Introduction.pptx business communication
DOCX
unit 1 COST ACCOUNTING AND COST SHEET
PDF
COST SHEET- Tender and Quotation unit 2.pdf
PPT
340036916-American-Literature-Literary-Period-Overview.ppt
PPTX
job Avenue by vinith.pptxvnbvnvnvbnvbnbmnbmbh
PDF
Ôn tập tiếng anh trong kinh doanh nâng cao
PPTX
New Microsoft PowerPoint Presentation - Copy.pptx
Roadmap Map-digital Banking feature MB,IB,AB
Dragon_Fruit_Cultivation_in Nepal ppt.pptx
3. HISTORICAL PERSPECTIVE UNIIT 3^..pptx
Deliverable file - Regulatory guideline analysis.pdf
Stem Cell Market Report | Trends, Growth & Forecast 2025-2034
Katrina Stoneking: Shaking Up the Alcohol Beverage Industry
NewBase 12 August 2025 Energy News issue - 1812 by Khaled Al Awadi_compresse...
svnfcksanfskjcsnvvjknsnvsdscnsncxasxa saccacxsax
Probability Distribution, binomial distribution, poisson distribution
HR Introduction Slide (1).pptx on hr intro
Elevate Cleaning Efficiency Using Tallfly Hair Remover Roller Factory Expertise
Power and position in leadershipDOC-20250808-WA0011..pdf
Amazon (Business Studies) management studies
Lecture (1)-Introduction.pptx business communication
unit 1 COST ACCOUNTING AND COST SHEET
COST SHEET- Tender and Quotation unit 2.pdf
340036916-American-Literature-Literary-Period-Overview.ppt
job Avenue by vinith.pptxvnbvnvnvbnvbnbmnbmbh
Ôn tập tiếng anh trong kinh doanh nâng cao
New Microsoft PowerPoint Presentation - Copy.pptx

Asynchronous JS in Odoo