Repository: sveltejs/svelte (JavaScript)
Date: 2017-12-05 03:00:10+00:00
Task type: Bug Fix

Issue:
await throws error with null anchor
Love the await block, but ran into an issue with cases where an anchor isn't needed (which I think could be relatively often). 

Example: https://svelte.technology/repl?version=1.44.1&gist=2280c071cccd0dbc9cf0b873540c2c4f

I think the following line needs a guard for `null` anchor value (`needsAnchor = false`), but I'm not sure what it should look like: 

https://github.com/sveltejs/svelte/blob/7e40ee220142dd23a0e4a626f670cb29a187ff68/src/generators/dom/visitors/AwaitBlock.ts#L70. 





Issue discussion:

Solution patch:
diff --git a/src/generators/dom/visitors/AwaitBlock.ts b/src/generators/dom/visitors/AwaitBlock.ts
--- a/src/generators/dom/visitors/AwaitBlock.ts
+++ b/src/generators/dom/visitors/AwaitBlock.ts
@@ -67,7 +67,7 @@ export default function visitAwaitBlock(
 				${old_block}.u();
 				${old_block}.d();
 				${await_block}.c();
-				${await_block}.m(${anchor}.parentNode, ${anchor});
+				${await_block}.m(${state.parentNode || `${anchor}.parentNode`}, ${anchor});
 			}
 		}
 
@@ -142,6 +142,10 @@ export default function visitAwaitBlock(
 		`);
 	}
 
+	block.builders.unmount.addBlock(deindent`
+		${await_block}.u();
+	`);
+
 	block.builders.destroy.addBlock(deindent`
 		${await_token} = null;
 		${await_block}.d();


Test patch:
diff --git a/test/runtime/samples/await-then-catch-anchor/_config.js b/test/runtime/samples/await-then-catch-anchor/_config.js
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/await-then-catch-anchor/_config.js
@@ -0,0 +1,49 @@
+let fulfil;
+
+let thePromise = new Promise(f => {
+	fulfil = f;
+});
+
+export default {
+	data: {
+		thePromise
+	},
+
+	html: `
+		<div><p>loading...</p></div>
+	`,
+
+	test(assert, component, target) {
+		fulfil(42);
+
+		return thePromise
+			.then(() => {
+				assert.htmlEqual(target.innerHTML, `
+					<div><p>the value is 42</p></div>
+				`);
+
+				let reject;
+
+				thePromise = new Promise((f, r) => {
+					reject = r;
+				});
+
+				component.set({
+					thePromise
+				});
+
+				assert.htmlEqual(target.innerHTML, `
+					<div><p>loading...</p></div>
+				`);
+
+				reject(new Error('something broke'));
+
+				return thePromise.catch(() => {});
+			})
+			.then(() => {
+				assert.htmlEqual(target.innerHTML, `
+					<div><p>oh no! something broke</p></div>
+				`);
+			});
+	}
+};
diff --git a/test/runtime/samples/await-then-catch-anchor/main.html b/test/runtime/samples/await-then-catch-anchor/main.html
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/await-then-catch-anchor/main.html
@@ -0,0 +1,9 @@
+<div>
+{{#await thePromise}}
+<p>loading...</p>
+{{then theValue}}
+<p>the value is {{theValue}}</p>
+{{catch theError}}
+<p>oh no! {{theError.message}}</p>
+{{/await}}
+</div>
diff --git a/test/runtime/samples/await-then-catch-if/_config.js b/test/runtime/samples/await-then-catch-if/_config.js
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/await-then-catch-if/_config.js
@@ -0,0 +1,45 @@
+let fulfil;
+
+const thePromise = new Promise(f => {
+	fulfil = f;
+});
+
+export default {
+	data: {
+		show: true,
+		thePromise
+	},
+
+	html: `
+		<p>loading...</p>
+	`,
+
+	test(assert, component, target) {
+		fulfil(42);
+
+		return thePromise
+			.then(() => {
+				assert.htmlEqual(target.innerHTML, `
+					<p>the value is 42</p>
+				`);
+
+				component.set({
+					show: false
+				});
+
+				assert.htmlEqual(target.innerHTML, `
+					<p>Else</p>
+				`);
+
+				component.set({
+					show: true
+				});
+
+				return thePromise.then(() => {
+					assert.htmlEqual(target.innerHTML, `
+						<p>the value is 42</p>
+					`);
+				});
+			});
+	}
+};
diff --git a/test/runtime/samples/await-then-catch-if/main.html b/test/runtime/samples/await-then-catch-if/main.html
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/await-then-catch-if/main.html
@@ -0,0 +1,11 @@
+{{#if show}}
+{{#await thePromise}}
+<p>loading...</p>
+{{then theValue}}
+<p>the value is {{theValue}}</p>
+{{catch theError}}
+<p>oh no! {{theError.message}}</p>
+{{/await}}
+{{else}}
+<p>Else</p>
+{{/if}}