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

Comments

@hadeeb
Copy link

hadeeb commented Apr 20, 2019

REPL

@EmilTholin
Copy link
Member

EmilTholin commented Apr 29, 2019

@colinbate
Copy link

@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
Copy link

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

@Conduitry
Copy link
Member

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
Copy link
Member

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
Copy link
Member

Fixed in 3.9.1, thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants