Svelte: How to subscribe to store inside a class instance

Viewed 649

How do I subscribe to a writable() instance of a class?

class User{
    public money: Writable<number> = writable(0);

    public goToJob(){
        money.update(prev => prev + 100);
    }
}

<script>
    let user = new User();
</script>

<div>{user.$money}</div>
<button on:click={() => user.goToJob()}>Go to Job</button>

When I click on the button, I expect the money to be added and reflected on the div. It doesn't update however, though I'm correctly referencing the money store.

2 Answers

Solved; Quite easy actually. Just de-structure the class instance:

<script>
    let user = new User();
    let { money } = user;
</script>

<div>{$money}</div>
<button on:click={() => user.goToJob()}>Go to Job</button>

Never saw a store as a Class property but instead store is often used as kind of a DTO. I know nothing about typescript but I think the below code is gonna give you a better idea of what I'm talking about:

<script>
    import user from './user-store.js';
  
    {
        $user // This automatically subscribes and unsubscribe to the User store.
    }
    
    $user = {money:100};
</script>

<div>{$user.money}</div>

<button on:click={() => user.goToJob()}>
Go to Job
</button>

Displaying or assigning a value to the store uses the $ prefix ($user.money) but calling a function doesn't (user.goToJob())

import { writable } from 'svelte/store';

const user = writable({}); // the store is an empty object by default

const userStore = {
  subscribe: user.subscribe,
  set: u => {
    user.set(u);
    console.log(u);
  },
    
  delete: () => {
    user.set(null);
  },
    
    goToJob: () => {
    user.update(user => {
             user.money += 100;
             return user;
        });
  }
};

export default userStore;

Link here:

https://svelte.dev/repl/ec4a3dee9f3c4bbebf929ee5772c48c5?version=3.46.2

Best.

Related