Combining E() and form.JSONMap() renders without getting a promise?

I'm fiddling with luci-app-example to add some more examples of how to work with LuCI and Javascript.
I have two functions that take data and build forms/tables from the data. One uses E() and the other uses JSONMap. The render() function looks like:

render_sample2_using_jsonmap: function (sample) {
  var m = new form.JSONMap(sample, _('JSONMap'), _('Description'));
  return m;
render: function (data) {
        var sample1 = data[0] || {};
        var sample2 = data[1] || {};

        return E('div', { 'class': 'cbi-map', 'id': 'map' }, [
            E('div', { 'class': 'cbi-section' }, [
                E('div', { 'class': 'left' }, [
                    E('h3', _('Sample 1 using JS array to make a table')),
                E('div', { 'class': 'left' }, [
                    E('h3', _('Sample 2 using JSONMap to make a form')),

render_sample2_using_jsonmap() returns m; m is defined as new form.JSONMap().

The rendered view shows the table built for sample1 correctly, and the header for sample2. However, sample2's render() call is returning [object Promise].

Is it possible to force the form's render() method to actually execute, instead of of returning the promise?

I know I can do an inverse here, and embed E() generated DOM nodes inside a form's content (luci-app-wireguard does this), but that feels like a dirty hack for a case where I want to show some data using E(), and also have a viable form that can update a configuration.

This is what renders right now.

There is no way. You do need to await the form render promise, then build the DOM. Or build the DOM with an empty table placeholder, then update the table once the JSONMap render promise is fulfilled.

You may want to use the (unfortunately undocumented) LuCI.ui.Table class for this, see this commit for example usage:

Thanks @jow - was mostly experimentation that had me trying to fit tabular data and a form on the same view, but this doesn't seem to be that common a paradigm in OpenWrt UIs, so maybe I'll skip that idea for now (though, I suppose the 'install/remove software' page is precisely this kind of UI). Might poke the Table thing later on and see what I can do with it.