Repository: sveltejs/svelte (JavaScript)
Date: 2017-07-29 15:51:01+00:00
Task type: Bug Fix

Issue:
Call ondestroy before cleanup
So that `this.refs` is still populated, etc. From [this Gitter convo](https://gitter.im/sveltejs/svelte?at=5963505876a757f808f5cc29)
Call ondestroy before cleanup
So that `this.refs` is still populated, etc. From [this Gitter convo](https://gitter.im/sveltejs/svelte?at=5963505876a757f808f5cc29)


Issue discussion:
Huh, seems this already happens in the expected order. @stalkerg can you provide a repro showing the bug you mentioned in Gitter (the Charts.js thing)?
A possible reproduction help: when I uncomment this line: https://github.com/TehShrike/svelte-1-25-0-array-binding-repro/blob/17e64d2b7292b824b8805b66443515cd411f11df/src/Top.html#L16 and start adding/removing elements by changing the number in the input, I observe some thrown errors.
@Rich-Harris please https://svelte.technology/repl?version=1.25.0&gist=c111d07479b9e65c9476bcb246944113
(you should watch logs and decrease number)
the main problem then you start using IF statement.
Huh, seems this already happens in the expected order. @stalkerg can you provide a repro showing the bug you mentioned in Gitter (the Charts.js thing)?
A possible reproduction help: when I uncomment this line: https://github.com/TehShrike/svelte-1-25-0-array-binding-repro/blob/17e64d2b7292b824b8805b66443515cd411f11df/src/Top.html#L16 and start adding/removing elements by changing the number in the input, I observe some thrown errors.
@Rich-Harris please https://svelte.technology/repl?version=1.25.0&gist=c111d07479b9e65c9476bcb246944113
(you should watch logs and decrease number)
the main problem then you start using IF statement.

Solution patch:
diff --git a/src/generators/dom/visitors/Element/Ref.ts b/src/generators/dom/visitors/Element/Ref.ts
--- a/src/generators/dom/visitors/Element/Ref.ts
+++ b/src/generators/dom/visitors/Element/Ref.ts
@@ -17,7 +17,7 @@ export default function visitRef(
 		`#component.refs.${name} = ${state.parentNode};`
 	);
 
-	block.builders.unmount.addLine(deindent`
+	block.builders.destroy.addLine(deindent`
 		if ( #component.refs.${name} === ${state.parentNode} ) #component.refs.${name} = null;
 	`);
 


Test patch:
diff --git a/test/runtime/samples/ondestroy-before-cleanup/Top.html b/test/runtime/samples/ondestroy-before-cleanup/Top.html
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/ondestroy-before-cleanup/Top.html
@@ -0,0 +1,9 @@
+<div ref:element></div>
+
+<script>
+	export default {
+		ondestroy() {
+			this.refOnDestroy = this.refs.element;
+		}
+	};
+</script>
diff --git a/test/runtime/samples/ondestroy-before-cleanup/_config.js b/test/runtime/samples/ondestroy-before-cleanup/_config.js
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/ondestroy-before-cleanup/_config.js
@@ -0,0 +1,9 @@
+export default {
+	test(assert, component, target) {
+		const top = component.refs.top;
+		const div = target.querySelector('div');
+
+		component.set({ visible: false });
+		assert.equal(top.refOnDestroy, div);
+	}
+};
\ No newline at end of file
diff --git a/test/runtime/samples/ondestroy-before-cleanup/main.html b/test/runtime/samples/ondestroy-before-cleanup/main.html
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/ondestroy-before-cleanup/main.html
@@ -0,0 +1,18 @@
+{{#if visible}}
+	<Top ref:top></Top>
+{{/if}}
+
+<script>
+	import Top from './Top.html';
+	
+	export default {
+		data() {
+			return {
+				visible: true
+			};
+		},
+		components: {
+			Top
+		}
+	};
+</script>
\ No newline at end of file