From 5fd4965b647db670a16e2c2634b6ed98697c6c9f Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sun, 29 Apr 2018 09:48:17 -0400 Subject: [PATCH] preserve outer context for await blocks - fixes #1251 --- src/compile/nodes/AwaitBlock.ts | 8 ++--- test/runtime/samples/await-in-each/_config.js | 31 +++++++++++++++++++ test/runtime/samples/await-in-each/main.html | 7 +++++ 3 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 test/runtime/samples/await-in-each/_config.js create mode 100644 test/runtime/samples/await-in-each/main.html diff --git a/src/compile/nodes/AwaitBlock.ts b/src/compile/nodes/AwaitBlock.ts index 87e1f7a850..60ce1ad23d 100644 --- a/src/compile/nodes/AwaitBlock.ts +++ b/src/compile/nodes/AwaitBlock.ts @@ -98,6 +98,8 @@ export default class AwaitBlock extends Node { block.addVariable(promise); block.addVariable(resolved); + block.maintainContext = true; + // the `#component.root.set({})` below is just a cheap way to flush // any oncreate handlers. We could have a dedicated `flush()` method // but it's probably not worth it @@ -119,13 +121,12 @@ export default class AwaitBlock extends Node { } } - function ${handle_promise}(${promise}, ctx) { + function ${handle_promise}(${promise}) { var ${token} = ${await_token} = {}; if (@isPromise(${promise})) { ${promise}.then(function(${value}) { ${this.value ? deindent` - var ctx = #component.get(); ${resolved} = { ${this.value}: ${value} }; ${replace_await_block}(${token}, ${create_then_block}, @assign(@assign({}, ctx), ${resolved})); ` : deindent` @@ -133,7 +134,6 @@ export default class AwaitBlock extends Node { `} }, function (${error}) { ${this.error ? deindent` - var ctx = #component.get(); ${resolved} = { ${this.error}: ${error} }; ${replace_await_block}(${token}, ${create_catch_block}, @assign(@assign({}, ctx), ${resolved})); ` : deindent` @@ -155,7 +155,7 @@ export default class AwaitBlock extends Node { } } - ${handle_promise}(${promise} = ${snippet}, ctx); + ${handle_promise}(${promise} = ${snippet}); `); block.builders.create.addBlock(deindent` diff --git a/test/runtime/samples/await-in-each/_config.js b/test/runtime/samples/await-in-each/_config.js new file mode 100644 index 0000000000..6912341d66 --- /dev/null +++ b/test/runtime/samples/await-in-each/_config.js @@ -0,0 +1,31 @@ +let fulfil; + +let thePromise = new Promise(f => { + fulfil = f; +}); + +const items = [{ + title: 'a title', + data: thePromise +}]; + +export default { + data: { + items + }, + + html: ` +

a title: loading...

+ `, + + test(assert, component, target) { + fulfil(42); + + return thePromise + .then(() => { + assert.htmlEqual(target.innerHTML, ` +

a title: 42

+ `); + }); + } +}; \ No newline at end of file diff --git a/test/runtime/samples/await-in-each/main.html b/test/runtime/samples/await-in-each/main.html new file mode 100644 index 0000000000..a928f933aa --- /dev/null +++ b/test/runtime/samples/await-in-each/main.html @@ -0,0 +1,7 @@ +{#each items as item} + {#await item.data} +

{item.title}: loading...

+ {:then result} +

{item.title}: {result}

+ {/await} +{/each} \ No newline at end of file