javascriptxmlodoorpcodoo-14

How to get rpc response data to display in inherited template?


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?


Solution

  • 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]);
          });
        },
      });