Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I export a function from a Svelte component that changes a value in the component?

I have a component called WastedTime.svelte with a value wastedTime. There's also a function to change the value to 50 (in my real code, this does an animation but this is a reduced test case for Stack Overflow).

To allow the child function to be called from a parent, I have used <script context="module"> per the Svelte docs:

<script context="module">
    var wastedTime = 0;
    export function changeNumber(){
        console.log('changing number')
        wastedTime = 50
    }
</script>

<script>
    // Putting 'var wastedTime = 0' here doesn't work either
</script>


<h1>Wasted time: {wastedTime}</h1>

The parent calls the function in the child from onMount:

<script>

    import { onMount } from 'svelte';
    import WastedTime, {changeNumber } from './WastedTime.svelte';

    onMount(() => {
        changeNumber()
    });
</script>

<WastedTime />

The problem is that since wastedTime is referred to in <script context="module">, it can't seem to change wastedTime. The exported function runs, but wastedTime stays at 0.

Copy of this on Svelte REPL

I have tried: - Putting var wastedTime = 0 in <script context="module"> - Putting var wastedTime = 0 in <script>

Neither works.

How can I export a function from a Svelte component that changes a value in the component?

like image 542
mikemaccana Avatar asked Oct 08 '19 13:10

mikemaccana


People also ask

How do I export component svelte?

Exporting a Svelte component </h1> ); export default GreetMessage; Once you've created your class or functional React component, you must use the export keyword or you can use export default to export that React component. In Svelte, by default it's exported as soon you create your Svelte file!

Can you export a function?

You can export as many functions as needed as long as you remember that there can be only one default export. The default export in JavaScript is used to export a single/fallback value from a module. With a default export, you do not need to specify a name for the exported function. The filename is used by default.

Can we export function in angular?

There's one more export method – 'default export'. When you don't specify certain name (omit curly braces) of 'import', the 'default export' will be imported. In the 'default export' you can use random alias for 'import'. This will fire the same function as previous example and log into browser console 'Greetings'.

What is context module svelte?

Posted on: April 26, 2022 by Md Niaz Rahman Khan. In this article, you are going to learn about how to use the context module in svelte. In svelte, module context is the way of sharing code from one component to another. Suppose, you are creating an e-commerce application with svelte.

What is svelte’s export keyword?

In this case Svelte is using the export keyword to mark a variable declaration as a property or prop, which means it becomes accessible to consumers of the component. You can also specify a default initial value for a prop.

How to bind a variable exported from one component to another?

If you export a variable in the child component you can bind it in the parent by using bind:var={local}property where varis the variable name in the child component and localis the parent's local variable. Two.svelte --> <script> // since the variable is exported we can bind

How does svelte'extend'JavaScript?

This is how Svelte 'extends' JavaScript by taking valid syntax and giving it a new purpose. In this case Svelte is using the export keyword to mark a variable declaration as a property or prop, which means it becomes accessible to consumers of the component. You can also specify a default initial value for a prop.

How does svelte generate the code for reactive statements?

Svelte will generate the code to automatically update them whenever data they depend on is changed. Note: Svelte uses the $: JavaScript label statement syntax to mark reactive statements. Just like the export keyword being used to declare props, this may look a little alien.


Video Answer


2 Answers

<script context="module"> isn't reactive — changes to variables inside this block won't affect individual instances (unless you were changing a store value, and every instance was subscribed to that store).

Instead, export the changeNumber function directly from the instance, and get a reference to it with bind:this:

WastedTime.svelte

<script>
    var someNumber = 0;
    export function changeNumber(){
        console.log('changing number')
        someNumber = 56
    }
</script>

<h1>Wasted time: {someNumber}</h1>

App.svelte

<script>
    import { onMount } from 'svelte';
    import WastedTime from './WastedTime.svelte';

    let wastedTimeComponent;

    onMount(() => {
        wastedTimeComponent.changeNumber()
    });
</script>

<WastedTime bind:this={wastedTimeComponent} />

Demo here: https://svelte.dev/repl/f5304fef5c6e43edb8bf0d25d634f965

like image 96
Rich Harris Avatar answered Oct 13 '22 09:10

Rich Harris


Simplified version of Rich's answer:

App.svelte

<script>
import Time from './Time.svelte';

let timeComponent;
let time;
</script>

<Time bind:this={timeComponent} bind:time />

<h1>Spent time: {time} ms</h1>

{#if timeComponent}
  <button on:click={() => timeComponent.spendTime() }>Click me</button>
{:else}
  Loading...
{/if}

Time.svelte

<script>
export var time = 0;
export function spendTime() {
  time += 50;
}
</script>

The key here is export function.

like image 6
Ben Bucksch Avatar answered Oct 13 '22 08:10

Ben Bucksch