Repository: sveltejs/svelte (JavaScript)
Date: 2017-12-13 01:02:01+00:00
Task type: Bug Fix

Issue:
await blocks break inside components
[REPL](https://svelte.technology/repl?version=1.47.1&gist=a27426d394dbea15e7100cac856936a9). If the `await` block is wrapped in an element, it works fine, but not as the direct child of a component.


Issue discussion:

Solution patch:
diff --git a/src/generators/nodes/AwaitBlock.ts b/src/generators/nodes/AwaitBlock.ts
--- a/src/generators/nodes/AwaitBlock.ts
+++ b/src/generators/nodes/AwaitBlock.ts
@@ -69,6 +69,7 @@ export default class AwaitBlock extends Node {
 		const name = this.var;
 
 		const anchor = this.getOrCreateAnchor(block, parentNode);
+		const updateMountNode = this.getUpdateMountNode(anchor);
 
 		const params = block.params.join(', ');
 
@@ -107,7 +108,7 @@ export default class AwaitBlock extends Node {
 					${old_block}.u();
 					${old_block}.d();
 					${await_block}.c();
-					${await_block}.m(${parentNode || `${anchor}.parentNode`}, ${anchor});
+					${await_block}.m(${updateMountNode}, ${anchor});
 				}
 			}
 
diff --git a/src/generators/nodes/Text.ts b/src/generators/nodes/Text.ts
--- a/src/generators/nodes/Text.ts
+++ b/src/generators/nodes/Text.ts
@@ -1,7 +1,6 @@
 import { stringify } from '../../utils/stringify';
 import Node from './shared/Node';
 import Block from '../dom/Block';
-import { State } from '../dom/interfaces';
 
 // Whitespace inside one of these elements will not result in
 // a whitespace node being created in any circumstances. (This


Test patch:
diff --git a/test/runtime/samples/await-then-catch-in-slot/Foo.html b/test/runtime/samples/await-then-catch-in-slot/Foo.html
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/await-then-catch-in-slot/Foo.html
@@ -0,0 +1 @@
+<slot></slot>
\ No newline at end of file
diff --git a/test/runtime/samples/await-then-catch-in-slot/_config.js b/test/runtime/samples/await-then-catch-in-slot/_config.js
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/await-then-catch-in-slot/_config.js
@@ -0,0 +1,49 @@
+let fulfil;
+
+let thePromise = new Promise(f => {
+	fulfil = f;
+});
+
+export default {
+	data: {
+		thePromise
+	},
+
+	html: `
+		<p>loading...</p>
+	`,
+
+	test(assert, component, target) {
+		fulfil(42);
+
+		return thePromise
+			.then(() => {
+				assert.htmlEqual(target.innerHTML, `
+					<p>the value is 42</p>
+				`);
+
+				let reject;
+
+				thePromise = new Promise((f, r) => {
+					reject = r;
+				});
+
+				component.set({
+					thePromise
+				});
+
+				assert.htmlEqual(target.innerHTML, `
+					<p>loading...</p>
+				`);
+
+				reject(new Error('something broke'));
+
+				return thePromise.catch(() => {});
+			})
+			.then(() => {
+				assert.htmlEqual(target.innerHTML, `
+					<p>oh no! something broke</p>
+				`);
+			});
+	}
+};
\ No newline at end of file
diff --git a/test/runtime/samples/await-then-catch-in-slot/main.html b/test/runtime/samples/await-then-catch-in-slot/main.html
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/await-then-catch-in-slot/main.html
@@ -0,0 +1,17 @@
+<Foo>
+	{{#await thePromise}}
+		<p>loading...</p>
+	{{then theValue}}
+		<p>the value is {{theValue}}</p>
+	{{catch theError}}
+		<p>oh no! {{theError.message}}</p>
+	{{/await}}
+</Foo>
+
+<script>
+	import Foo from './Foo.html';
+
+	export default {
+		components: { Foo }
+	};
+</script>
\ No newline at end of file