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

Bug? observe trigger behaviour #395

Open
Fiddlekins opened this issue Nov 12, 2024 · 0 comments
Open

Bug? observe trigger behaviour #395

Fiddlekins opened this issue Nov 12, 2024 · 0 comments

Comments

@Fiddlekins
Copy link

Fiddlekins commented Nov 12, 2024

Firstly just want to give praise to this library, of the myriad Proxy based libs I definitely prefer the explicit get and set behaviour this one offers. I've been trying it out by refitting a hobby project that I'd built using basic useContext+useState and for the most part it's been pretty smooth, though I've had to trial and error a few areas the docs don't go into too much detail about.

The issue I've run into and been unable to figure out what seems to be an intended approach revolves around a computed value failing to trigger an observe callback when expected.

This following is executed using 3.0.0-beta.16.

Apologies for these examples being a bit long, but I couldn't figure out how to boil them down much more:

interface SubType {
  subVal: number;
}

const baseVal: SubType[] = [
  {subVal: 1},
];

const a$ = observable({
  aVal: [] as SubType[],
});

const b$ = observable({
  bVal: () => {
    return [
      ...baseVal,
      ...a$.aVal.get(),
    ];
  },
});

observe(() => {
  // The following line is required for `a$.aVal[0].subVal.set(3);` to trigger an update
  // a$.aVal.get();

  const data = b$.bVal.get();
  console.log('called', JSON.stringify(data));
});

a$.aVal.push({subVal: 2});
a$.aVal[0].subVal.set(3);

console.log('end', JSON.stringify(a$.aVal.get()), JSON.stringify(b$.bVal.get()));

Run this, and we get logged out:

called [{"subVal":1}]
called [{"subVal":1},{"subVal":2}]
end [{"subVal":3}] [{"subVal":1},{"subVal":3}]

If we uncomment the a$.aVal.get(); line, we instead have the following logged:

called [{"subVal":1}]
called [{"subVal":1},{"subVal":2}]
called [{"subVal":1},{"subVal":3}]
end [{"subVal":3}] [{"subVal":1},{"subVal":3}]

As we see, the observe callback doesn't trigger when the subVal is set to 3 by using bVal.get() alone. Instead we need to also call aVal.get() to register an additional listener.

In contrast to this too is the following example, where we switch the comlpex SubType for a primitive:

const baseVal: number[] = [
  1,
];

const a$ = observable({
  aVal: [] as number[],
});

const b$ = observable({
  bVal: () => {
    return [
      ...baseVal,
      ...a$.aVal.get(),
    ];
  },
});

observe(() => {
  // The following line is not required for `a$.aVal[0].set(3);` to trigger an update
  // a$.aVal.get();

  const data = b$.bVal.get();
  console.log('called', JSON.stringify(data));
});

a$.aVal.push(2);
a$.aVal[0].set(3);

console.log('end', JSON.stringify(a$.aVal.get()), JSON.stringify(b$.bVal.get()));

Without the additional listener we get the following logged:

called [1]
called [1,2]
called [1,3]
end [3] [1,3]

So to conclude, whilst I'm not 100% certain what the intended behaviour is, this does strike me as a bug since the primitive example works as I would have expected it whilst the complex subtype does not.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant