Search code examples
sveltesvelte-3svelte-component

How to write a method that uses global variable in Svelte?


I'm currently working on my first Svelte project, and have run into a problem with recyclability of code.

I have a few components that use the same functionality, so of course I want to put the shared functionality in a file where my components can import methods from.

I have run into a problem where the methods that I import does not know about variables that are attached to my component.

Minimal, working example (code below);

https://svelte.dev/repl/59170f8e82274215a0b64692c3e4613c?version=3.55.0

In this example App import the transformName method, but does not know about name. When looking at the two components, Greetings and Goodbye you can see that I have made the exact same method in both components which works as expected.

App.svelte

    <script>
    import Greeting from './Greeting.svelte'
    import Goodbye from './Goodbye.svelte'
    import {transformName} from './transformName.js'
    
    let name = 'globalName';
    </script>
    <Greeting name="world"/>
    <Goodbye name="my friend"/>
    <h1>Hello {transformName()}!</h1>

transformName.js

export function transformName() {
    return name.toUpperCase();
}

Goodbye.svelte

<script>
    export let name;
    
    function transformName() {
        return name.toUpperCase();
    }
</script>
<div>
    Goodbye {transformName()}
</div>

Greeting.svelte

Greeting.svelte

<script>
    export let name;
    
    function transformName() {
        return name.toUpperCase();
    }
</script>
<div>
    Hello, {transformName()}
</div>

I've thought of just taking in the name as a parameter to the method, but that feels redundant and I would have to refactor a lot of code for this approach to work.

So, my question is; Is it possible to write a method that can be in a separate file and still know about variables on the component it is imported into?


Solution

  • You only have to pass a variable to the method. I've changed a litle your REPL and you could try this new https://svelte.dev/repl/6d19efc4316b483eb64d2a00262baf1d?version=3.55.0

    In resume, in transformName.js:

    export function transformName(name) {
      return name.toUpperCase();
    }
    

    And App.svelte:

    <h1>Hello {transformName(name)}!</h1>