From 1dad4df4e34dca851fe3f82ad9ca3684d7fd5ccc Mon Sep 17 00:00:00 2001 From: Jay Meistrich Date: Thu, 21 Sep 2023 18:15:51 +0200 Subject: [PATCH] Fix updateNodes not notifying when assigning --- src/ObservableObject.ts | 8 +++++++- tests/tests.test.ts | 14 ++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/ObservableObject.ts b/src/ObservableObject.ts index 3deb4ca62..2dfb2c772 100644 --- a/src/ObservableObject.ts +++ b/src/ObservableObject.ts @@ -213,7 +213,7 @@ function updateNodes(parent: NodeValue, obj: Record | Array | und } } - if (obj && !isPrimitive(obj) && !parent.lazy) { + if (obj && !parent.lazy && !isPrimitive(obj)) { hasADiff = hasADiff || length !== lengthPrev; const isArrDiff = hasADiff; let didMove = false; @@ -556,6 +556,12 @@ function setKey(node: NodeValue, key: string, newValue?: any, level?: number) { // Get the child node for updating and notifying const childNode: NodeValue = isRoot ? node : getChildNode(node, key); + if (childNode.lazy) { + // Make sure the node is activated when assigning because the node + // is never accessed through the proxy + peek(childNode); + } + // Set the raw value on the parent object const { newValue: savedValue, prevValue, parentValue } = setNodeValue(childNode, newValue); diff --git a/tests/tests.test.ts b/tests/tests.test.ts index 3d9822d8b..62bc48031 100644 --- a/tests/tests.test.ts +++ b/tests/tests.test.ts @@ -511,6 +511,20 @@ describe('Listeners', () => { { path: ['test'], pathTypes: ['object'], valueAtPath: { test2: 'hi' }, prevAtPath: undefined }, ]); }); + test('Start undefined assign something', () => { + interface Data { + test?: undefined | { test2: string }; + } + const obs = observable({}); + const handler = expectChangeHandler(obs); + + obs.assign({ test: { test2: 'hi' } }); + + // TODO: The previous value here is not totally correct because it filled out the path to make set work + expect(handler).toHaveBeenCalledWith({ test: { test2: 'hi' } }, { test: undefined }, [ + { path: ['test'], pathTypes: ['object'], valueAtPath: { test2: 'hi' }, prevAtPath: undefined }, + ]); + }); test('Set with object should only fire listeners once', () => { interface Data { test: undefined | Record;