In svelte, how to `console.log('yes')` when a variable changed?
Asked Answered
W

5

37
let c = 0;
$: console.log(c);

If we want to print the value of c when it is changed, we can write like above.

Because c is used in $ directive literally, so this statement can be reactive to c.

But what if I just want to console.log('yes') when c is changed?

let c = 0;
$: console.log('yes');

Obviously, the statement console.log('yes') is not reactive to c.

Furthermore, if I still console.log(c) but put it into a function:

let c = 0;
function log() {
  console.log(c);
}
$: log();

log() is also not reactive to c.

So, what can I do if the reactive code doesn't literally contain the variable which I want to reactive to?

Wiltshire answered 11/7, 2019 at 7:37 Comment(1)
A very good read on Svelte Reactivity with examples and explanations sveltesociety.dev/recipes/svelte-language-fundamentals/…Kilowatt
W
75

I asked in Twitter, the answer from Svelte creator Rich Harris is:

The most common way to handle that situation is $: c, console.log('yes'); It does feel a bit weird, I know :)

Wiltshire answered 11/7, 2019 at 10:49 Comment(3)
Thanks for coming back with the answer, staring this for future reference. I really wish this was outlined in the svelte docs.Loiret
Wow, this is quite the golden nugget of info. I would not have guessed to use a comma-separated statement after $:, which is new to me anyway. Is this a valid/better way to operate than having to put boo.far = boo.far whenever you think it might make a difference, in terms of updating a state (cos sometimes for some reason I don't, while other times I do - it's still a bit of a mystery)?Locke
One big problem with this is that it doesn't expose the previous value, so this will trigger on page instantiation as well as user triggered update.Aged
L
9

I have recently been playing with svelte and needed to call a function when a property changed.
In Vue you would do it with watch, but I could not find an equivilent in Svelte.
In my project have done it like this:

let c = 0;
$: if (c) {
    console.log("yes");
}

I am not 100% sure if this is the correct way or not though.
Hopefully Rich Harris will chime in here as I would like to know.

Loiret answered 11/7, 2019 at 9:6 Comment(3)
I've @Rich_Harris in Twitter, if he responses, I'll sync here.Wiltshire
You may use shorter syntax like $: c ? console.log(yes):null;Dionne
One gotcha with this approach is if you want that code to run on every change, including a change from non-zero to zero. The $: if() approach won't run when the value becomes 0 (or any other falsy value).Endue
H
1

You can do it like this:

let c = 0;
$: if (c >= 0) {
    console.log("yes");
}
Hanni answered 11/7, 2019 at 8:12 Comment(4)
change c from 1 to 0 will not do log...but it's another thread about the false value in javascript.Wiltshire
your intention is to write c literally in $ statement, although it looks strange. It's a workaround, we can also write console.log('yes' || c) or c; console.log('yes');, but they are all ugly...Wiltshire
I updated my answer to include 0. This if statement can be adjusted to include negative values as well should you need that.Hanni
c; console.log('yes') doesn't look so ugly to meRonni
M
1

It also works if you just use the changing variable inside whatever you want to do:

let c
$: if (condition) console.log(c)
Miry answered 7/2, 2021 at 16:17 Comment(0)
E
0

Guys you got it all wrong. You can just do

let c = 0;

setInterval(() => c++; , 5000);
$: console.log(c);

Because svelte compiler will notice console.log takes C as a parameter. And because console.log is called using reactive statement. It will call your reactive statement every times C changes, so every 5000ms

Electronic answered 12/9, 2023 at 14:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.