I created a table in d3.js and return it as a div.node()
and I am trying to render it in svelte.
It's created with fetched data so I wrap it inside an sveltes asynchronous await syntax:
<div>
{#await fetched}
<p>...waiting</p>
{:then result}
{@html result}
{/await}
</div>
where fetched is the result of the following:
function getData()
{
return fetch("path").then(d => tabulate(d.json(), ['col', 'col2']));
}
let fetched = getData();
However, what is returned on the page is [object HTMLDivElement]
instead of the actual table. The docs say it needs to be standalone HTML, I rendered it in a file and it worked.
Should I create the element first in svelte and then select it instead?
It works if I select a pre-existing div.
The accompanying d3.js function full credit to jfreels:
function tabulate(data, columns) {
const div = d3.create("div")
let table = div.append('table')
let thead = table.append('thead')
let tbody = table.append('tbody');
// append the header row
thead.append('tr')
.selectAll('th')
.data(columns).enter()
.append('th')
.text(function (column) { return column; });
// create a row for each object in the data
let rows = tbody.selectAll('tr')
.data(data)
.enter()
.append('tr');
// create a cell in each row for each column
let cells = rows.selectAll('td')
.data(function (row) {
return columns.map(function (column) {
return {column: column, value: row[column]};
});
})
.enter()
.append('td')
.text(function (d) { return d.value; });
return div.node();
}
CodePudding user response:
The object is a DOM element, not HTML; but since it is already a fully functional element, it is not necessary to write it as HTML and make the browser re-parse it. As Corrl noted, that would also cause all event listeners to be lost.
You can easily attach the node using e.g. an action:
const append = (node, child) => node.append(child);
<div>
{#await fetched}
<p>...waiting</p>
{:then result}
<div use:append={result} />
{/await}
</div>