Are there any examples in Discourse of decorating a widget after an ajax request?


(Steven Slade) #1

I would like to use api.decorateWidget after an Discourse.ajax has run.

api.decorateWidget('post-contents:before', dec => {
              const attrs = dec.attrs;
              const result = [];

              Discourse.ajax('/test', {
                type: 'GET',
                data: { topic_id: topic_id, group: group }
              }).then(function(res){
                if (res.test) {
                 //this push a virtual node into the result array
                  result.push(h('h1', 'test'));
                //this logs the virtual node and confirm virtual-dom works here
                  console.log(result);
              //expected result here is that api.decorateWidget gets the returned h1 virtual node and attached is, BUT it does nothing with no errors.
                  return result;
                }
             });

           });

#EDIT: AFTER RUNNING SOME TESTS
So what all the code boils down to is…

  1. The decorateWidget function
  2. An ajax call inside the decorateWidget
  3. An if statement in the result of the ajax call that returns a vDOM element

I put a console.log at each of these steps and got this (note: there are 2 posts on the thread I am testing on, which is why the widget decorator and ajax call runs twice):

Also, I am still not getting the vDOM element to return after the if statement.


Decorate a widget from inside an ajax success response
(OG) #2

I’d like to follow up on this thread. Is it possible to return results of ajax.then() to html function so it will display in widget rendered content?

The problem is that value is returned without waiting for ajax result.

export default createWidget('custom-widget', {
  html(attrs, state) {
    ajax("/customdata.json").then(data => {
      // some data formatting to html
      return `THIS WONT BE SHOWN`;
    });
    return `THIS IS SHOWN`;
  }
});

(OG) #3

The only solution I’ve found so far is to switch to Component and use bufferedRender and to observe for changes in local variable, then call re-render.

export default Ember.Component.extend(bufferedRender({

  @on("init")
  _updateContent() {
    if (!this.get('content')) {
      ajax("/growfaq.json").then(data => {
        this.set('content', data);
      });
    }
  }

  @observes('content')
  _rerenderOnChange() {
    this.rerenderBuffer();
  },

  
}));

Also