odoo / owl

OWL: A web framework for structured, dynamic and maintainable applications
https://odoo.github.io/owl/
Other
1.11k stars 334 forks source link

Error when using orm with useService in Odoo 17 #1564

Closed amir-rismani closed 7 months ago

amir-rismani commented 7 months ago

I am developing a small Todo List app on Odoo 17 to learn Owl. Everything was progressing smoothly until I attempted to dynamically fetch and display data using orm with useService. I encountered the following error:

Uncaught (in promise) TypeError: Cannot use 'in' operator to search for 'orm' in undefined

I have extensively tried to resolve the issue by consulting the Owl and Odoo documentation, as well as searching for solutions online, but without success. The code adheres to the documentation, and I am uncertain about the source of this error.

Steps to Reproduce:

  1. clone this repo somewhere
  2. start odoo with this repo in the addons-path, on a recent version (odoo 17)
  3. install the odoo_owl_app addon
  4. go to the /owl-app route to see the result.

Code: The root.js file contains the following codes:

/** @odoo-module */

import { Component, useState, useSubEnv, onWillStart } from "@odoo/owl";
import { useService } from "@web/core/utils/hooks";

import { WebsiteLayout } from "./layouts/website/layout"
import { TodoForm } from "./components/todo_form/todo_form";
import { Todos } from "./components/todos/todos";

export class Root extends Component {
    static template = "odoo_owl_app.root";
    static components = { WebsiteLayout, TodoForm, Todos };
    static props = {};

    setup() {
        this.todos = useState([]);
        this.orm = useService("orm");
        this.model = 'odoo_owl_app.todo';

        this.handleChangeState = (event) => {
            const id = event.target.value;
            const index = this.todos.findIndex(todo => todo.id === parseInt(id))
            this.todos[index].is_completed = !this.todos[index].is_completed
        };

        this.handleEdit = (id, title) => {
            const index = this.todos.findIndex(todo => todo.id === parseInt(id))
            this.todos[index].title = title
        };

        this.handleRemove = (id) => {
            console.log('remove', id)
            const index = this.todos.findIndex(todo => todo.id === parseInt(id))
            this.todos.splice(index, 1);
        };

        this.onAdd = (title) => {
            const todo = {
                userId: 1,
                id: new Date().getTime(),
                title,
                is_completed: false
            }
            this.todos.push(todo)
        };
    }
}

When this code this.orm = useService("orm"); is added to the setup, the following error is issued:

Uncaught (in promise) TypeError: Cannot use 'in' operator to search for 'orm' in undefined

Screenshot: Screenshot from 2023-12-01 18-58-50

Additional Information:

Projects:

I appreciate any assistance in resolving this issue and gaining a better understanding of using Owl with Odoo.

sdegueldre commented 7 months ago

Hello, the issue is that you're not starting the services so useService cannot possibly work. Try following this guide which I recently wrote: https://www.odoo.com/documentation/master/developer/howtos/standalone_owl_application.html

I'm going to close this issue as it is not related to Owl itself but how to use Owl within Odoo. If it is a bug or feature request it should be an issue on the Odoo repo, if it's an issue with using using the code or the tutorial it should be an issue on the documentation repo

amir-rismani commented 7 months ago

@sdegueldre You were right, I used mountComponent instead of mount to start the servers and the problem was solved.

thanks for your reply

Good luck

flotho commented 5 months ago

Hi @sdegueldre , thanks for your tips. I'm using your proposal with mountComponent yet as I follow you tuto on Odoo doc it looks like mountComponent should be part of @web/env AFAICS, there is no such method in @web/env , only in owl ... Ah my bad, available in 17.0 not in v16.

Maybe using startWebClient in @web/start could be a good choice ?

flotho commented 5 months ago

@sdegueldre You were right, I used mountComponent instead of mount to start the servers and the problem was solved.

thanks for your reply

Good luck

Could you share your solution ?

flotho commented 5 months ago

hum, looks like it works for a owl applicaton. What is the process to hook a component into a portal website page for example. I've succeed in mouting the component but wahrerver the method, impossible to have services. UseService failed either with the v16 or v17 flavor with mountComponent. Is it necessary to use OwlCompatibility because website still designed in old framework ? Regards

sdegueldre commented 5 months ago

If you want to be able to use useService your app's environment needs to contain the started services. In 17.0+ you can use mountComponent which does that for you automatically, but in lower versions you'll have to create your env yourself and start the services in that environment. You'll also need to make sure that the code for the services that you want to use and their dependencies are loaded in the correct assets bundle (assets_frontend for portal). I wouldn't recommend using startWebClient directly, as it does a few things that are specific to the actual webclient, but your starting code should do most of what startWebClient does.

In the website and portal, we already start the services and they can only be started once, so you'll have to reuse that env. I've replied to you on another issue about how to achieve this.

HamidAbdalla123 commented 2 weeks ago

Hi gays i have question, i need to patch some code to Order class that located in pos/app/store/models when i inherit setup function and i need to use orm services it show error

flotho commented 2 weeks ago

hi @HamidAbdalla123 , this issue is closed. Moreover you didn't provides enough details so we can't identify if its an owl or Odoo issue. Please open a proper issue.