odoo/owl

useService("user") doesn't work with public component

jujuna opened this issue · 6 comments

I have a public component and in this template i call another component LibraryData

<?xml version="1.0" encoding="UTF-8"?>
<templates>
    <t t-name="university_library.currentLibrary" owl="1">
        <div class="container d-flex flex-column">
            <div class="d-flex flex-column border border-primary m-2 shadow-sm rounded lib text-center lib_title">
                <div class="title mt-4">
                    <h3><t t-esc="this.state.lecture_name"/></h3>
                </div>
            </div>
            <LibraryData library_id="this.state.library_id"/>
        </div>
    </t>
</templates>

and in this component i wanna get info about current user, for that i use useService but data is undefined


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


export class LibraryData extends Component {
    static template = 'university_library.LibraryData'
    static props = {
        library_id: {type: String}
    };

    setup() {
        this.fileUploadService = useService("file_upload");
        this.userService = useService("user");
        this.orm = useService("orm");

        this.state = useState({
            "description": "",
            "data": [],
            "file": null,
            'description_req': false,
            'file_req': false
        })

        onWillStart(async () => {
            console.log('Started')
            await this.getAllData()
        });

    }

    async getAllData() {
        const domain = [["library_id", "=", this.props.library_id]];
        const modelId = await this.orm.searchRead("library.data", domain);

        modelId.forEach(record => {
            record.create_uid[1] = record.create_uid[1].split("-")[0].trim();
            record.create_date = record.create_date.split(" ")[0]
        });
        this.state.data = modelId
        console.log("Fetch")
    }

    async addNewData(e) {
        var file = document.getElementById('inputGroupFile01')
        var description = document.getElementById('name')

        this.state.description_req = !description.value
        this.state.file_req = !file.files.length

        if (description.value && file.files.length) {
            const uploadawait = new Promise((resolve, reject) => {
                this.fileUploadService.upload("/upload_file", file.files, {
                    buildFormData: (formData) => {
                        formData.append("res_model", 'library.data');
                        formData.append("library_id", this.props.library_id);
                        formData.append("description", description.value);
                    },
                });
            })

            file.value = ""
            description.value = ""
            $('#exampleModal').modal('hide');

            setTimeout(() => {
                this.getAllData()
            }, "200");
        }
    }

    async deleteData(e) {
        try {
            console.log(e.target)
            console.log(Number(e.target.id))
            await this.orm.unlink('library.data', [Number(e.target.id)]);
            console.log("deleted")
            $('#conf_modal').modal('hide')
            await this.getAllData()
        } catch (error) {
            console.log(error)
        }
    }
}

registry.category('public_components').add('lib_data', LibraryData)

image

Which version are you in? In 17.1 and up, user is no longer a service, it's just a file that you import.

I use 17.0. Which file is it?

I misread the issue. In 17.0 there is indeed a userService and it appears you're getting that service correctly but it doesn't have any data because that data is generally not needed in the frontend. The user service exposes the user-related data from the session_info, in the backend this data is generated by the session_info method in web/models/ir_http.py, while for the frontend it's defined by the get_frontend_session_info method on that same model. If you need more data in the user service in the frontend you'll need to override this second method and add info that's added by the first method. Keep in mind that in this context, user can be the public user so make sure to check access rights as necessary. If you just return extra data from this method with the same keys as the other method the user service will pick it up automatically.

I got it! but didn't understand why user_id is undefined in JS? i saw get_frontend_session_info method and it has 'user_id': user.id if session_uid else False,. you said because that data is generally not needed in the frontend. What do you mean exactly? Should i use it in template and then i will give access on JS?

Looks like user_id is unused, the correct field name would be uid (which will be exposed by the user service as userId) looks like a mistake in standard Odoo, it doesn't seem that any of the standard frontend code relies on the user id though.

Okay thank you very much for explanation! I will close it.