1

I am trying to get user data and then use it in the template. This is what I tried.

  var session = require('web.session');
  var rpc = require('web.rpc');

  var ListController = require('web.ListController');
  ListController.include({
    renderButtons: function($node) {
      this._super.apply(this, arguments);
      rpc.query({
        model: 'res.users',
        method: 'search_read',
        args: [
          [['id','=',session.uid]],
          ['id','name','login'],
        ],
      }).then(res => {
        this.user = res[0];
        console.log(this);
        // this._super.apply(this, arguments);
      });
    },
  });

It does log my desired user data. However, when I use it in the inherited template, it is giving me empty data.

<?xml version="1.0" encoding="UTF-8"?>
<template xml:space="preserve">
  <t t-extend="ListView.buttons">
    <t t-jquery="button.o_list_button_add" t-operation="replace">
      <button class="btn btn-primary o_list_button_add" type="button">Create</button>
      <span t-esc="widget.user"/>
    </t>
  </t>
 </template>

I tried changing the place of this._super.apply(this, arguments); to the line in the comment and remove it in the first line, but it gave me random untraceable errors.

I just want to get data from RPC and display it in the inherited template. How to achieve the task?

holydragon
  • 6,158
  • 6
  • 39
  • 62

1 Answers1

1

The issue that you are facing it's because you aren't taking into account the async nature of the js requests to the server.

What it's happening it's that the response of the request land when the template it's already rendered.

So you have 2 options:

  1. Manually replace the HTML Element value by hand when the response happens
<?xml version="1.0" encoding="UTF-8"?>
<template xml:space="preserve">
  <t t-extend="ListView.buttons">
    <t t-jquery="button.o_list_button_add" t-operation="replace">
      <button class="btn btn-primary o_list_button_add" type="button">Create</button>
      <span id="show_user_name"/>
    </t>
  </t>
 </template>
  ListController.include({
    renderButtons: function($node) {
      let self = this;
      this._super.apply(this, arguments);
      rpc.query({
        model: 'res.users',
        method: 'search_read',
        args: [
          [['id','=',session.uid]],
          ['id','name','login'],
        ],
      }).then(res => {
        self.user = res[0];
        $('#show_user_name').html(res[0]);
      });
    },
  });
  1. Or you need to wait for the response to happen in order to call the super function taking into account that if you do that you will need to create a variable to hold the value of this._super because it wouldn't be there to be called inside the response handling function. Something like this:
var ListController = require('web.ListController');
  ListController.include({
    renderButtons: function($node) {
      let self = this;
      let _super = this._super;
      rpc.query({
        model: 'res.users',
        method: 'search_read',
        args: [
          [['id','=',session.uid]],
          ['id','name','login'],
        ],
      }).then(res => {
        this.user = res[0];
        _super.apply(self,[$node]);
      });
    },
  });
aekis.dev
  • 2,626
  • 1
  • 12
  • 19
  • Your solutions are brilliant! I wanted to use the second option, but I couldn't get it to work. Maybe it is because some of my other elements and logic didn't go with it. So, I ended up adopting your first option, and it works like a charm! – holydragon Jul 27 '23 at 03:26
  • Thanks. So many years working with this kind of Odoo stuffs I have seen a lot. I'm open for business if you heard someone looking to solve something tricky or need some development and consultation services – aekis.dev Jul 27 '23 at 06:15