DOMException *sometimes* after changing element order

I have a solid-js website that populates an html table with data, using a <For /> to render, with a createResource() signal as the source for the list. After the data is rendered, the user can sort the table, which directly changes the order of the table rows in the DOM. When the refetch() is called on the resource, often a DOMException is thrown Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node. Here is a sandbox reproduction of the issue:
1. Click the Sort Data button 2. Click the Fetch Data button If you refresh the page, and do the fetch first, then sort, then fetch .. you can see that it does not throw in this case I have a feeling this has something to do with JSX and how the DOM is changed on a refetch ... like it has a reference to the old nodes before sorting Please help ... sorting the data inside of the createResource fetcher routine is not really an option here, as the sorting functionality is part of a much larger vanilla web-component that augments the plain html tables for us.
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
3 Replies
halu
halu3w ago
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
obesecoder
obesecoder3w ago
That does work thank you --- Also found after posting this that if I used straight js array mapping instead of <For/> that also seem to have fixed my issue
{!data.loading && data().map(item => (
<tr>
<td>{item.id}</td>
<td>{item.uid}</td>
<td>{item.city}</td>
<td>{item.street_name}</td>
<td>{item.street_address}</td>
</tr>
))}
{!data.loading && data().map(item => (
<tr>
<td>{item.id}</td>
<td>{item.uid}</td>
<td>{item.city}</td>
<td>{item.street_name}</td>
<td>{item.street_address}</td>
</tr>
))}
Dakotys
Dakotys3w ago
The reason why you were getting DOMException was because For firstly generates items, then when signal changes it just adjusts their order (very fast and optimized approach compared to mapping that has to expensively recreate whole table repetitively) but you are manually changing nodes in sortData() ( which is terrible idea in any reactive framework like solid or react, those things should be handled easier and more safely using framework's handlers) and that confuses Fors built in indexing and throws an error. So instead just update the signal returned from createResource (use mutate) : https://playground.solidjs.com/anonymous/303c972d-5c4c-43d8-b2d2-f5399b9c7025
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template