Skip to content
This repository was archived by the owner on Oct 16, 2024. It is now read-only.
This repository was archived by the owner on Oct 16, 2024. It is now read-only.

Computed value is not recomputed after dependencies change #219

Closed
@leopf

Description

@leopf

🐛 Bug report

I have a problem with not updating computed values. I am using a demo API to download and insert users into a collection. I want to use a computed value to get a user from this collection based on a user id, which is defined in a state. The first compute works with the default user id, but after updating the user id the value is not recomputed. I took a look at the deps prop and found all the necessary observers with the correct values, though the value of the computed user was incorrect.

The first compute only works if I define the computed value after inserting the users into the collection, otherwise this computed value is stuck on undefined.

🤖 Current Behavior

const data: any[] = await fetch('https://jsonplaceholder.typicode.com/users').then(res => res.json());

const userCollection = createCollection();
const selectedUserId = createState(1);
selectedUserId.watch(() => console.log("---- new selected user id!"));

for (const item of data) {
    userCollection.collect(item);
}

const selectedUser = createComputed(() => {
    return userCollection.getItemValue(selectedUserId.value);
});

console.log("auto:", selectedUser.value);
selectedUserId.set(2);
console.log("manual:", userCollection.getItemValue(selectedUserId.value));
console.log("auto:", selectedUser.value);
console.log(selectedUser.deps);

output:

auto: {
  id: 1,
  name: 'Leanne Graham',
  username: 'Bret',
  email: 'Sincere@april.biz',
  address: {
    street: 'Kulas Light',
    suite: 'Apt. 556',
    city: 'Gwenborough',
    zipcode: '92998-3874',
    geo: { lat: '-37.3159', lng: '81.1496' }
  },
  phone: '1-770-736-8031 x56442',
  website: 'hildegard.org',
  company: {
    name: 'Romaguera-Crona',
    catchPhrase: 'Multi-layered client-server neural-net',
    bs: 'harness real-time e-markets'
  }
}
---- new selected user id!
manual: {
  id: 2,
  name: 'Ervin Howell',
  username: 'Antonette',
  email: 'Shanna@melissa.tv',
  address: {
    street: 'Victor Plains',
    suite: 'Suite 879',
    city: 'Wisokyburgh',
    zipcode: '90566-7771',
    geo: { lat: '-43.9509', lng: '-34.4618' }
  },
  phone: '010-692-6593 x09125',
  website: 'anastasia.net',
  company: {
    name: 'Deckow-Crist',
    catchPhrase: 'Proactive didactic contingency',
    bs: 'synergize scalable supply-chains'
  }
}
auto: {
  id: 1,
  name: 'Leanne Graham',
  username: 'Bret',
  email: 'Sincere@april.biz',
  address: {
    street: 'Kulas Light',
    suite: 'Apt. 556',
    city: 'Gwenborough',
    zipcode: '92998-3874',
    geo: { lat: '-37.3159', lng: '81.1496' }
  },
  phone: '1-770-736-8031 x56442',
  website: 'hildegard.org',
  company: {
    name: 'Romaguera-Crona',
    catchPhrase: 'Multi-layered client-server neural-net',
    bs: 'harness real-time e-markets'
  }
}
Set(2) {
  StateObserver {
    agileInstance: [Function (anonymous)],
    key: undefined,
    dependents: Set(1) { [StateObserver] },
    subscribedTo: Set(0) {},
    value: 2,
    previousValue: 1,
    state: [Function (anonymous)],
    nextStateValue: 2
  },
  StateObserver {
    agileInstance: [Function (anonymous)],
    key: 2,
    dependents: Set(1) { [StateObserver] },
    subscribedTo: Set(0) {},
    value: {
      id: 2,
      name: 'Ervin Howell',
      username: 'Antonette',
      email: 'Shanna@melissa.tv',
      address: [Object],
      phone: '010-692-6593 x09125',
      website: 'anastasia.net',
      company: [Object]
    },
    previousValue: null,
    state: [Function (anonymous)],
    nextStateValue: {
      id: 2,
      name: 'Ervin Howell',
      username: 'Antonette',
      email: 'Shanna@melissa.tv',
      address: [Object],
      phone: '010-692-6593 x09125',
      website: 'anastasia.net',
      company: [Object]
    }
  }
}

🎯 Expected behavior

I would expect this to work, as defined in the docs.

const MY_COMPUTED = createComputed(() => {
    const user = USERS.getItemValue(CURRENT_USER_ID.value);
    return `My name is '${user?.name} and I am ${user?.age} years old.`;
});
MY_COMPUTED.value; // Returns "My name is 'hans' and I am 10 years old."
USERS.update(CURRENT_USER_ID.value, {name: 'jeff'})
MY_COMPUTED.value; // Returns "My name is 'jeff' and I am 10 years old." 

📄 Reproducible example

I created a simple main.ts file and ran it with ts-node.

import { createState, createCollection, createComputed } from "@agile-ts/core";
import fetch from 'cross-fetch';

async function init() {
    const data: any[] = await fetch('https://jsonplaceholder.typicode.com/users').then(res => res.json());

    const userCollection = createCollection();
    const selectedUserId = createState(1);
    selectedUserId.watch(() => console.log("---- new selected user id!"));

    for (const item of data) {
        userCollection.collect(item);
    }

    const selectedUser = createComputed(() => {
        return userCollection.getItemValue(selectedUserId.value);
    });

    console.log("auto:", selectedUser.value);
    selectedUserId.set(2);
    console.log("manual:", userCollection.getItemValue(selectedUserId.value));
    console.log("auto:", selectedUser.value);
    console.log(selectedUser.deps);
}

init();

💡 Suggested solution(s)

➕ Additional notes

💻 Your environment

Software Version(s)
TypeScript v4.5.4
npm/Yarn v8.3.2
NodeJs v14.18.2
@agile-ts/core v0.2.8
@agile-ts/react N/A
@agile-ts/api N/A
@agile-ts/multieditor N/A
ts-node v10.4.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    @agile-ts/coreRelated to the @agile-ts/core packagebugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions