S
SolidJS8mo ago
zimo

Failed to execute 'replaceChild' on 'Node': The node to be replaced is not a child of this node.

I have a store:
export const [mainStore, setMainStore] = createStore<StoreType>({ countries: undefined });
export const [mainStore, setMainStore] = createStore<StoreType>({ countries: undefined });
of this type:
export type StoreType = {
countries?: FrontEndCountry[]
}

export interface FrontEndCountry {
id: string
name: string
type?: string | null
parentCountryId?: string | null
subtitle?: string | null
description?: string | null
countrySprites: FrontEndSprite[]
}

export interface FrontEndSprite {
lat: number
lng: number
z: number
scale: number
mapName: string
countryId: string
}
export type StoreType = {
countries?: FrontEndCountry[]
}

export interface FrontEndCountry {
id: string
name: string
type?: string | null
parentCountryId?: string | null
subtitle?: string | null
description?: string | null
countrySprites: FrontEndSprite[]
}

export interface FrontEndSprite {
lat: number
lng: number
z: number
scale: number
mapName: string
countryId: string
}
I'm trying to render only part of these countries, or rather their sprites. I filter them out and render them like this:
<For each={mainStore.countries?.filter(c => {

const countryIsExtra = !countryNames.includes(c.name);
const extraSelected = characters().includes("extra");

if (countryIsExtra && !extraSelected)
return false;

const countrySelected = characters().includes("countries");
if (!countryIsExtra && !countrySelected)
return false;

const hasSelectedSkin = c.countrySprites.filter(s => s.mapName === mapSkin()).length > 0;
if (!hasSelectedSkin)
return false;

return true;
})}>
{(country, ix) => {
return <MapCountry countrySprite={country.countrySprites.filter(s => s.mapName === mapSkin())[0]} />
}}
</For>
<For each={mainStore.countries?.filter(c => {

const countryIsExtra = !countryNames.includes(c.name);
const extraSelected = characters().includes("extra");

if (countryIsExtra && !extraSelected)
return false;

const countrySelected = characters().includes("countries");
if (!countryIsExtra && !countrySelected)
return false;

const hasSelectedSkin = c.countrySprites.filter(s => s.mapName === mapSkin()).length > 0;
if (!hasSelectedSkin)
return false;

return true;
})}>
{(country, ix) => {
return <MapCountry countrySprite={country.countrySprites.filter(s => s.mapName === mapSkin())[0]} />
}}
</For>
In short you can toggle between different mapSkin() and different characters(), both of which currently have two settings. It works OK when you go from no characters selected to a few selected, or when you seemingly replace all the sprites, but as soon as the resulting list expands or contracts I get the omnious error:
Error: Failed to execute 'replaceChild' on 'Node': The node to be replaced is not a child of this node.
Error: Failed to execute 'replaceChild' on 'Node': The node to be replaced is not a child of this node.
I have had this error for a few weeks now. Am I using stores incorrectly?
6 Replies
zimo
zimoOP8mo ago
@ryansolid I came across your reply here: https://github.com/solidjs/solid/discussions/366#discussioncomment-459799 It might be able to help me. I am trying out your <Key> implementation but do you think reconcile and createState are better? I have never used them before and I would guess they require a lot more set up?
ryansolid
ryansolid8mo ago
Key only works one level deep basically. Where the reconcile and store can diff down to a greater level of detail. I usually go for stores.
zimo
zimoOP8mo ago
Thanks for the answer! Sadly I am already using a store and I still have problems (OP). I'm going through the tutorial again for now. I have a store to hold all the local data fetched so far from the back-end, but maybe I need another store that more closely resembles my web GUI? I.e. a list of Countries that should be rendered as elements instead of trying to conditionally extract a subset from my main store?
ryansolid
ryansolid8mo ago
Hmm.. that's an odd error, it suggests that DOM nodes are getting moved in an unexpected way. That's a rendering error. The store is probably related, but this error happens when there are references to DOM nodes.. things getting inserted outside of the framework usually..
zimo
zimoOP8mo ago
You were right. I am passing the elements to mapbox-gl which is a bit unpredictable when it creates/removes markers using these provided components. It changed the DOM in in a way Solid seemingly can't predict, which is also inefficient. Instead I opted to load all possible countries (which could be 1000s) and try to hide their main content with a <Show>. Hopefully this is how it should be done, because I don't fully knows how Solid works under the hood, but I guess it gets messed up when its own proxy doesn't conform to the DOM.
ryansolid
ryansolid8mo ago
Yeah Solid doesn't observe the DOM and just keeps references. It assumes it is in the state it is left in from a declarative standpoint. There is some flexibility in terms of being able to augment on top of that but if it falls back to Solid doing updates from declarative templates it won't have known if things have moved when it expects them to be there.
Want results from more Discord servers?
Add your server