Skip to content

Commit 5f1a36d

Browse files
committed
fix(core): double check for falsy parent in removeChild
1 parent 08c27e5 commit 5f1a36d

File tree

2 files changed

+24
-12
lines changed

2 files changed

+24
-12
lines changed

libs/core/src/lib/renderer/index.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,14 @@ export class NgtRenderer implements Renderer2 {
286286
untracked(() => getLocalState(oldChild)?.parent)) as NgtRendererNode;
287287
}
288288

289+
// if parent is still falsy, we don't know what to do with the parent.
290+
// we'll just remove the child and destroy it
291+
if (!parent) {
292+
removeThreeChild(oldChild, undefined, true);
293+
this.destroyInternal(oldChild, undefined);
294+
return;
295+
}
296+
289297
const pRS = parent.__ngt_renderer__;
290298
const cRS = oldChild.__ngt_renderer__;
291299

@@ -306,7 +314,7 @@ export class NgtRenderer implements Renderer2 {
306314
}
307315

308316
if (pRS[NgtRendererClassId.type] === 'three' && cRS[NgtRendererClassId.type] === 'three') {
309-
removeThreeChild(parent, oldChild, true);
317+
removeThreeChild(oldChild, parent, true);
310318
this.destroyInternal(oldChild, parent);
311319
return;
312320
}
@@ -522,13 +530,13 @@ export class NgtRenderer implements Renderer2 {
522530
for (const renderChild of rS[NgtRendererClassId.children] || []) {
523531
if (renderChild.__ngt_renderer__?.[NgtRendererClassId.type] === 'three' && parent) {
524532
if (parent.__ngt_renderer__?.[NgtRendererClassId.type] === 'three') {
525-
removeThreeChild(parent, renderChild, true);
533+
removeThreeChild(renderChild, parent, true);
526534
continue;
527535
}
528536

529537
const closestInstance = getClosestParentWithInstance(parent);
530538
if (closestInstance) {
531-
removeThreeChild(closestInstance, renderChild, true);
539+
removeThreeChild(renderChild, closestInstance, true);
532540
}
533541
}
534542
this.destroyInternal(renderChild, parent);

libs/core/src/lib/renderer/utils.ts

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ export function attachThreeChild(parent: NgtInstanceNode, child: NgtInstanceNode
121121
invalidateInstance(parent);
122122
}
123123

124-
export function removeThreeChild(parent: NgtInstanceNode, child: NgtInstanceNode, dispose?: boolean) {
124+
export function removeThreeChild(child: NgtInstanceNode, parent?: NgtInstanceNode, dispose?: boolean) {
125125
const pLS = getLocalState(parent);
126126
const cLS = getLocalState(child);
127127

@@ -132,12 +132,14 @@ export function removeThreeChild(parent: NgtInstanceNode, child: NgtInstanceNode
132132
pLS?.remove(child, 'objects');
133133
pLS?.remove(child, 'nonObjects');
134134

135-
if (cLS?.attach) {
136-
detach(parent, child, cLS.attach);
137-
} else if (is.object3D(parent) && is.object3D(child)) {
138-
parent.remove(child);
139-
const store = cLS?.store || pLS?.store;
140-
if (store) removeInteractivity(store, child);
135+
if (parent) {
136+
if (cLS?.attach) {
137+
detach(parent, child, cLS.attach);
138+
} else if (is.object3D(parent) && is.object3D(child)) {
139+
parent.remove(child);
140+
const store = cLS?.store || pLS?.store;
141+
if (store) removeInteractivity(store, child);
142+
}
141143
}
142144

143145
const isPrimitive = cLS?.primitive;
@@ -151,11 +153,13 @@ export function removeThreeChild(parent: NgtInstanceNode, child: NgtInstanceNode
151153
queueMicrotask(() => child['dispose']());
152154
}
153155

154-
invalidateInstance(parent);
156+
if (parent) {
157+
invalidateInstance(parent);
158+
}
155159
}
156160

157161
function removeThreeRecursive(array: NgtInstanceNode[], parent: NgtInstanceNode, dispose: boolean) {
158-
if (array) [...array].forEach((child) => removeThreeChild(parent, child, dispose));
162+
if (array) [...array].forEach((child) => removeThreeChild(child, parent, dispose));
159163
}
160164

161165
export function processThreeEvent(

0 commit comments

Comments
 (0)