Search code examples
odooodoo-15

How to use bus.bus to connect python and js?


please give some advise about the bus.bus mechanism. I want that after calling the python function of the model, another function is called on the client side, also i want to call js function on every active user. for example:

.py

MyModel(models.Model):
    ...
    def my_func(self):
        #do_stuff
        self.env['bus.bus']._sendone(...)  # or something like this

.js

export class MyComponent extends Component {

    constructor(...args) {
        super(...args);
        // here i wanna connect event to function test()  
    }

    test() {
        console.log('works');
    }
}

how can I do this?


Solution

  • well, after some time of research, I found a solution how to implement such a mechanism. first i tried to create my own channel for bus.bus but it didn't work for me so i went a trickier way. I use the already existing activity_updated channel and send a notification to it with the required parameter that will mark my activity. so, here is my code:

    *.py

    here i can send signal to all partners i need in any place i want.

    update_counters - is a parameter to mark just my actions and do not run any another

    self.env['bus.bus']._sendmany([
        [i, 'mail.activity/updated', {'update_counters': True}] for i in self.partner_ids
    ])
    

    *.js

    export class AppsBar extends Component {
    
        constructor(...args) {
            super(...args);
            Component.env.bus.on('activity_updated', this, this.update_counters);
            this.my_counter = 0;
            this.update_counters();
        }
        
        async update_counters(data) {
            var do_this = false;
            if (data === undefined) {
                do_this = true;
            } else if (typeof data == "object") {
                if ('update_counters' in data) {
                    do_this = true;
                }
            }
            if (do_this) {
                var rpc = require('web.rpc');
                var rpc_data = await rpc.query({
                    model: 'res.users',
                    method: 'get_counters',
                    args: [[]],
                });
                this.my_counter= rpc_data['my_counter'];
                this.render()
            }
        }
    }
    
    

    Component.env.bus.on('activity_updated', this, this.update_counters); - this is my subscription to signal