Repository: sveltejs/svelte (JavaScript)
Date: 2017-11-18 19:30:44+00:00
Task type: Bug Fix

Issue:
Each block inside slotted content does not get updated
I ran across a slight issue with each blocks and slotted content: if the each block outputs directly to a slot, the state updates are not rendered. If the each block is wrapped with an element, it works:

https://svelte.technology/repl?version=1.41.3&gist=64a25260abf9c36de5bb0b4d244499e7


Issue discussion:

Solution patch:
diff --git a/src/generators/dom/visitors/EachBlock.ts b/src/generators/dom/visitors/EachBlock.ts
--- a/src/generators/dom/visitors/EachBlock.ts
+++ b/src/generators/dom/visitors/EachBlock.ts
@@ -21,7 +21,7 @@ export default function visitEachBlock(
 	const iterations = block.getUniqueName(`${each}_blocks`);
 	const params = block.params.join(', ');
 
-	const needsAnchor = node.next ? !isDomNode(node.next, generator) : !state.parentNode;
+	const needsAnchor = node.next ? !isDomNode(node.next, generator) : !state.parentNode || !isDomNode(node.parent, generator);
 	const anchor = needsAnchor
 		? block.getUniqueName(`${each}_anchor`)
 		: (node.next && node.next.var) || 'null';
@@ -219,7 +219,7 @@ function keyed(
 	`);
 
 	const dynamic = node._block.hasUpdateMethod;
-	const parentNode = state.parentNode || `${anchor}.parentNode`;
+	const parentNode = isDomNode(node.parent, generator) ? node.parent.var : `${anchor}.parentNode`;
 
 	let destroy;
 	if (node._block.hasOutroMethod) {
@@ -414,7 +414,7 @@ function unkeyed(
 		.map(dependency => `changed.${dependency}`)
 		.join(' || ');
 
-	const parentNode = state.parentNode || `${anchor}.parentNode`;
+	const parentNode = isDomNode(node.parent, generator) ? node.parent.var : `${anchor}.parentNode`;
 
 	if (condition !== '') {
 		const forLoopBody = node._block.hasUpdateMethod


Test patch:
diff --git a/test/runtime/samples/component-slot-each-block/Nested.html b/test/runtime/samples/component-slot-each-block/Nested.html
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/component-slot-each-block/Nested.html
@@ -0,0 +1,3 @@
+<div>
+	<slot/>
+</div>
\ No newline at end of file
diff --git a/test/runtime/samples/component-slot-each-block/_config.js b/test/runtime/samples/component-slot-each-block/_config.js
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/component-slot-each-block/_config.js
@@ -0,0 +1,24 @@
+export default {
+	data: {
+		things: [1, 2, 3]
+	},
+
+	html: `
+		<div>
+			<span>1</span>
+			<span>2</span>
+			<span>3</span>
+		</div>`,
+
+	test(assert, component, target) {
+		component.set({ things: [1, 2, 3, 4] });
+		assert.htmlEqual(target.innerHTML, `
+			<div>
+				<span>1</span>
+				<span>2</span>
+				<span>3</span>
+				<span>4</span>
+			</div>
+		`);
+	}
+};
diff --git a/test/runtime/samples/component-slot-each-block/main.html b/test/runtime/samples/component-slot-each-block/main.html
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/component-slot-each-block/main.html
@@ -0,0 +1,13 @@
+<Nested>
+	{{#each things as thing}}
+		<span>{{thing}}</span>
+	{{/each}}
+</Nested>
+
+<script>
+	import Nested from './Nested.html';
+
+	export default {
+		components: { Nested }
+	};
+</script>
\ No newline at end of file