typescriptsveltesvelte-5

Handling potential null external svelte 5 state


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.


Solution

  • 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.