I have an external state with an exported getter in file.svelte.ts
:
let data: T | null = $state(null);
export function get_data() {
return data;
}
A component should use this state, however the component's logic does not allow for the state to be null.
So, I tried $derived.by
:
<script lang="ts">
import { navigate } from "svelte-routing";
import { get_data } from "file.svelte";
let data: T = $derived.by(() => {
let external = get_data();
if (!external) navigate("/null-error-page");
return external;
});
</script>
This gives off a typescript error because a navigate()
call does not terminate the function's execution. How can i call navigate()
such that it completely stops the loading of the component?
EDIT: I can!t just move the logic into an onMount
call, i need the component to call navigate()
whenever that external state is set to null.
What you need is $effect
. Derivations should be pure for the most part, and navigation is a side effect. If, however, you need this to run in the server, an effect will not do the trick because effects don't run in the SSR side of Svelte.
What I would do is let the derived value be null, then check it during component initialization:
<script lang="ts">
import ...
let data = $derived(get_data());
if (!data) {
navigate(...);
}
// Set up the same check in an effect.
$effect(() => {
if (!data) {
navigate(...);
}
});
</script>
I don't have the time to test right now. If for any reason you get into trouble because the effect is running too, just use a control variable to stop the effect.