Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect context in child component inside await #2443

Closed
hadeeb opened this issue Apr 20, 2019 · 6 comments · Fixed by #3442
Closed

Incorrect context in child component inside await #2443

hadeeb opened this issue Apr 20, 2019 · 6 comments · Fixed by #3442
Labels
bug

Comments

@hadeeb
Copy link

@hadeeb hadeeb commented Apr 20, 2019

REPL

@EmilTholin

This comment has been minimized.

Copy link
Member

@EmilTholin EmilTholin commented Apr 29, 2019

@colinbate

This comment has been minimized.

Copy link

@colinbate colinbate commented Jun 18, 2019

@EmilTholin This issue is biting me when trying to use the {#await ...} block to render a <Link> component from your svelte-routing. It only happens if the route with async <Link> is the initial one to load. If you transition to the route via another link, it doesn't have this issue as the Route isn't in init, it is in flush.

I thought about raising this in svelte-routing (and let me know if I still should), but it is directly related to this context/current_component issue.

@JanTvrdik

This comment has been minimized.

Copy link

@JanTvrdik JanTvrdik commented Jul 21, 2019

Is there any known workaround to this issue other than simply not using context at all?

@Conduitry

This comment has been minimized.

Copy link
Member

@Conduitry Conduitry commented Jul 21, 2019

I'd argue that not using {#await} is a more viable workaround. Context lets you do things not otherwise possible, while {#await} is mostly a convenience over updating certain bits of state when a promise stored in another variable resolves or rejects.

@Conduitry

This comment has been minimized.

Copy link
Member

@Conduitry Conduitry commented Jul 29, 2019

Naive fix:

diff --git a/src/runtime/internal/await_block.ts b/src/runtime/internal/await_block.ts
index 3834ff7c..14f68d5c 100644
--- a/src/runtime/internal/await_block.ts
+++ b/src/runtime/internal/await_block.ts
@@ -1,4 +1,5 @@
 import { assign, is_promise } from './utils';
+import { get_current_component, set_current_component } from './lifecycle';
 import { check_outros, group_outros, transition_in, transition_out } from './transitions';
 import { flush } from './scheduler';
 
@@ -40,9 +41,12 @@ export function handle_promise(promise, info) {
 	}
 
 	if (is_promise(promise)) {
+		const current_component = get_current_component();
 		promise.then(value => {
+			set_current_component(current_component);
 			update(info.then, 1, info.value, value);
 		}, error => {
+			set_current_component(current_component);
 			update(info.catch, 2, info.error, error);
 		});
 
diff --git a/src/runtime/internal/lifecycle.ts b/src/runtime/internal/lifecycle.ts
index d659fd2e..0ca3e430 100644
--- a/src/runtime/internal/lifecycle.ts
+++ b/src/runtime/internal/lifecycle.ts
@@ -6,7 +6,7 @@ export function set_current_component(component) {
 	current_component = component;
 }
 
-function get_current_component() {
+export function get_current_component() {
 	if (!current_component) throw new Error(`Function called outside component initialization`);
 	return current_component;
 }

This doesn't break any existing tests, and at first glance seems to fix the issue here. I have no idea whether this is a good idea.

Rich-Harris added a commit that referenced this issue Aug 21, 2019
Rich-Harris added a commit that referenced this issue Aug 22, 2019
set context in await blocks
@Rich-Harris

This comment has been minimized.

Copy link
Member

@Rich-Harris Rich-Harris commented Aug 22, 2019

Fixed in 3.9.1, thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
6 participants
You can’t perform that action at this time.