Enable Dark Mode!
how-to-create-owl-mixin-in-odoo-19.jpg
By: Arjun V P

How to Create Owl mixin in Odoo 19

Technical Odoo 19 Owl

With the continued evolution of Odoo’s JavaScript framework, OWL (Odoo Web Library) remains the backbone of Odoo’s modern front-end architecture. In Odoo 19, OWL provides even better component-based development, reactivity, and extensibility.

One powerful feature developers frequently rely on is mixins, a mechanism that allows you to share reusable logic across components.

In this blog, we will walk you through what an OWL mixin is, why it is useful, and how to create and use a custom mixin in Odoo 19.

What is an OWL mixin?

An OWL mixin is a simple JavaScript object that contains reusable functions or lifecycle behavior.

Adding the mixin to an OWL component allows you to extend its functionality without inheritance, keeping your code modular and clean.

Mixins are useful for:

  • Logging
  • Event handling
  • Common UI behavior
  • Shared utility functions
  • Enhancing components dynamically

Step-by-Step Guide to Creating an OWL Mixin in Odoo 19

Step 1: Create the Module Structure

First, create your custom Odoo module with the following structure:

owl_mixin/
+-- __init__.py
+-- __manifest__.py
+-- static/
¦   +-- src/
¦       +-- js/
¦           +-- mixin.js
¦           +-- owl.js
¦           +-- service.js

Step 2: Define the Manifest File

Create your __manifest__.py:

{
    'name': 'OWL Mixin Demo',
    'version': '19.0.1.0.0',
    'category': 'Technical',
    'summary': 'Demonstrates OWL Mixin pattern in Odoo 19',
    'depends': ['web'],
    'assets': {
        'web.assets_backend': [
            'owl_mixin/static/src/js/mixin.js',
            'owl_mixin/static/src/js/owl.js',
            'owl_mixin/static/src/js/service.js',
        ],
    },
    'installable': True,
    'application': False,
}

Step 3: Create the Mixin

Now, let's create the actual mixin in mixin.js:

/** @odoo-module **/
/**
 * LoggerMixin
 * Adds reusable logging behavior to OWL components
 */
export function LoggerMixin(BaseComponent) {
    return class extends BaseComponent {
        setup() {
            super.setup();
            console.log("[LOGGER MIXIN] setup executed");
        }
        logInfo(message) {
            console.log("[LOGGER MIXIN][INFO]", message);
        }
        logWarn(message) {
            console.warn("[LOGGER MIXIN][WARN]", message);
        }
        logError(message) {
            console.error("[LOGGER MIXIN][ERROR]", message);
        }
    };
}

Step 4: Create a Component Using the Mixin

In owl.js, create a component that uses the mixin:

/** @odoo-module **/
import { Component, onMounted, xml } from "@odoo/owl";
import { LoggerMixin } from "./mixin";
/**
 * Base component
 */
class LoggerDemoBase extends Component {
    static template = xml`<div class="logger-demo">Logger Demo Component</div>`;
    
    setup() {
        super.setup();
        console.log("[LOGGER DEMO] Base setup");
    }
}
/**
 * Final component with mixin applied
 */
export class LoggerDemo extends LoggerMixin(LoggerDemoBase) {
    setup() {
        super.setup();
        this.logInfo("LoggerDemo initialized");
        onMounted(() => {
            console.log('[Logger Demo Test]');
            this.logWarn("Sample warning log");
            this.logError("Sample error log");
        });
    }
}

Step 5: Register as a Service (For Testing)

In service.js, create a service to auto-start your component:

/** @odoo-module **/
import { registry } from "@web/core/registry";
import { LoggerDemo } from "./owl";
import { mount } from "@odoo/owl";
/**
 * Auto-start LoggerDemo for console demonstration
 */
registry.category("services").add("logger_mixin_demo", {
    start(env) {
        console.log("[LOGGER DEMO] Service starting...");
        
        // Create a hidden container for the component
        const container = document.createElement('div');
        container.style.display = 'none';
        document.body.appendChild(container);
        
        // Mount the component
        mount(LoggerDemo, container, { env });
        
        console.log("[LOGGER DEMO] Service started and component mounted");
    },
});

Understanding How It Works

The mixin pattern in OWL works through composition rather than traditional inheritance:

  1. LoggerMixin is a Higher-Order Function: It takes a base component class and returns a new class that extends it
  2. Method Injection: The mixin adds new methods (logInfo, logWarn, logError) to any component
  3. Lifecycle Hook Enhancement: The setup() method is augmented while preserving the base behavior via super.setup()
  4. Multiple Mixins: You can chain multiple mixins together like: MixinA(MixinB(MixinC(BaseComponent)))

Best Practices

  1. Keep mixins focused: Each mixin should have a single responsibility
  2. Always call super.setup(): Ensure the component lifecycle works correctly
  3. Document your mixins: Add clear JSDoc comments explaining what the mixin does
  4. Avoid state in mixins: Prefer utility functions over stateful logic
  5. Use descriptive names: Name mixins based on what they provide (e.g., LoggerMixin, ValidationMixin)

Conclusion

OWL mixins in Odoo 19 provide a clean, powerful way to share functionality across components. By using the composition pattern, you can build modular, maintainable code that's easy to test and extend. Whether you're adding logging, validation, or any other cross-cutting concern, mixins keep your components lean and focused on their primary responsibilities.

To read more about An Overview of OWL Components in Odoo 18, refer to our blog An Overview of OWL Components in Odoo 18.


If you need any assistance in odoo, we are online, please chat with us.



0
Comments



Leave a comment



whatsapp_icon
location

Calicut

Cybrosys Technologies Pvt. Ltd.
Neospace, Kinfra Techno Park
Kakkancherry, Calicut
Kerala, India - 673635

location

Kochi

Cybrosys Technologies Pvt. Ltd.
1st Floor, Thapasya Building,
Infopark, Kakkanad,
Kochi, India - 682030.

location

Bangalore

Cybrosys Techno Solutions
The Estate, 8th Floor,
Dickenson Road,
Bangalore, India - 560042

Send Us A Message