Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to get previous value in stores with dependencies? #31

Open
jorgecarleitao opened this issue Jul 6, 2023 · 1 comment
Open

How to get previous value in stores with dependencies? #31

jorgecarleitao opened this issue Jul 6, 2023 · 1 comment
Labels
enhancement New feature or request

Comments

@jorgecarleitao
Copy link

Assume we are in a store where product information is retrieved from API based on the basket the user has.

export const basket: Asyncable<Basket> = asyncable(
      load_basket,
      save_basket,
);

async function init_products(basket: Promise<Basket>) {}

export const products: Asyncable<Products> = asyncable(
    init_products,
    undefined,
    [basket]
);

Basically, products async manages data from API and depends on what basket contains. products should only fetch what it still does not have from basket (i.e. given a change to basket, I need to compute the delta and only fetch the missing data points from the API).

I am struggling to implement init_products. Specifically:

  • init_products receives the state of the basket, but it has no access to the current state of products. Therefore, it cannot optimize API fetches based on the products it already has on changes to basket.
  • update_products is not defined (/ never used) because this store is not used directly - its use is derived from what basket has (or at least I was unable to make asyncable call it by changing basket.
  • I can not use await products.get() inside init_products as it is circular.

Is there an idiom to achieve this?

@jorgecarleitao jorgecarleitao changed the title How to get previous value in stores with dependencies How to get previous value in stores with dependencies? Jul 6, 2023
@PaulMaly
Copy link
Member

Hi! NIce example to discuss and looks like very relevant case for svelte-asyncable. Thanks for your question.

Actually the only reason you can't just use await products.get() inside the getter function right now is that asyncable store default value is pending promise which is resolving by very first subscriber only once per store life-cycle. So, only thing you need to do to use await products.get() inside the getter function is to somehow check that getter was completed at least once before you wants to get current value of asyncable store.

Solution below is ugly a little, but it would work in your case. Probably, I need to think how to solve this particular case automatically. I'll think about it at my leisure. Hope it would help you.

export const basket: Asyncable<Basket> = asyncable(
      load_basket,
      save_basket,
);

export const products: Asyncable<Products> = asyncable(
    init_products,
    undefined,
    [basket]
);

let resolved = false;
async function init_products(basket: Promise<Basket>) {
    if (resolved) {
         const $products  = await products.get();
         const loadedProducts = await load_products(basket.filter(...));
         return [ ...$products, ...loadedProducts ];
    }
    resolved = true;
    return  load_products(basket);
}

@PaulMaly PaulMaly added the enhancement New feature or request label Jul 12, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants