diff --git a/src/observer.ts b/src/observer.ts index ba1a8acf..3883c717 100644 --- a/src/observer.ts +++ b/src/observer.ts @@ -18,6 +18,9 @@ const ModifiedArrayProto = Object.create(ArrayProto); for (let method of methodsToPatch) { const initialMethod = ArrayProto[method]; ModifiedArrayProto[method] = function(...args) { + if (!this.__observer__.allowMutations) { + throw new Error(`Array cannot be changed here")`); + } this.__observer__.notifyChange(); this.__owl__.rev++; let parent = this; @@ -122,12 +125,12 @@ export class Observer { return value; }, set(newVal) { - if (!self.allowMutations) { - throw new Error( - `State cannot be changed outside a mutation! (key: "${key}", val: "${newVal}")` - ); - } if (newVal !== value) { + if (!self.allowMutations) { + throw new Error( + `Observed state cannot be changed here! (key: "${key}", val: "${newVal}")` + ); + } self.unobserve(value); value = newVal; self.observe(newVal, obj); diff --git a/tests/observer.test.ts b/tests/observer.test.ts index f04f0f71..1c0dfdd5 100644 --- a/tests/observer.test.ts +++ b/tests/observer.test.ts @@ -279,4 +279,26 @@ describe("observer", () => { await nextMicroTick(); expect(observer.notifyCB).toBeCalledTimes(4); }); + + test("throw error when state is mutated in object if allowMutation=false", async () => { + const observer = new Observer(); + observer.allowMutations = false; + const obj: any = { a: 1 }; + observer.observe(obj); + + expect(() => { + obj.a = 2; + }).toThrow('Observed state cannot be changed here! (key: "a", val: "2")'); + }); + + test("throw error when state is mutated in array if allowMutation=false", async () => { + const observer = new Observer(); + observer.allowMutations = false; + const obj: any = { a: [1] }; + observer.observe(obj); + + expect(() => { + obj.a.push(2); + }).toThrow("Array cannot be changed here"); + }); });