immer-adapter icon indicating copy to clipboard operation
immer-adapter copied to clipboard

Error: TypeError: 'ownKeys' on proxy: trap result did not include 'scope'

Open xmlking opened this issue 6 years ago • 18 comments

after switching to @ngxs-labs/immer-adapter": "^2.0.1", i am getting following error

  @Mutation()
  @Action(CreateNewConversation)
  createConversation(ctx: StateContext<ChatBoxStateModel>) {
    const newConversation = new Conversation('payload.conversationId'); 
    ctx.setState((state: ChatBoxStateModel) => {
      state.conversations.push(newConversation);
      state.activeConversationId = newConversation.id;
      return state;
    });
  }
core.js:5567 ERROR TypeError: 'ownKeys' on proxy: trap result did not include 'scope'
    at Function.freeze (<anonymous>)
    at deepFreeze (ngxs-store.js:1514)
    at ngxs-store.js:1529
    at Array.forEach (<anonymous>)
    at deepFreeze (ngxs-store.js:1519)
    at Object.setState (ngxs-store.js:1607)
    at setStateValue (ngxs-store.js:1728)
    at Object.setState (ngxs-store.js:1785)
    at Object.setState (ngxs-labs-immer-adapter.js:82)
    at ChatBoxState.push.../../libs/chat-box/src/lib/state/chat-box.store.ts.ChatBoxState.createConversation (chat-box.store.ts:192)

xmlking avatar Apr 08 '19 05:04 xmlking

You need disabled development mode

splincode avatar Apr 08 '19 05:04 splincode

However, this is a bug and I need to reproduce it.

splincode avatar Apr 08 '19 06:04 splincode

Here is my project when you can reproduce https://github.com/xmlking/ngx-starter-kit/blob/develop/libs/chat-box/src/lib/state/chat-box.store.ts

xmlking avatar Apr 08 '19 14:04 xmlking

@xmlking well I was able to reproduce the error

image

splincode avatar Apr 08 '19 19:04 splincode

Fixed

image

splincode avatar Apr 08 '19 22:04 splincode

I cannot import import { ImmutableContext, ImmutableSelector } from '@ngxs-labs/immer-adapter'; some how they are missing in published v3.0.0 npm module!

image

xmlking avatar Apr 09 '19 03:04 xmlking

Sorry

splincode avatar Apr 09 '19 05:04 splincode

done (v3.0.1)

splincode avatar Apr 09 '19 05:04 splincode

No problem. appreciate your work and quick release 👍

xmlking avatar Apr 09 '19 08:04 xmlking

Again

ERROR TypeError: 'ownKeys' on proxy: trap result did not include 'scope' at Function.freeze () at deepFreeze (ngxs-store.js:1420) at ngxs-store.js:1435 at Array.forEach () at deepFreeze (ngxs-store.js:1425) at ngxs-store.js:1435 at Array.forEach () at deepFreeze (ngxs-store.js:1425) at Object.setState (ngxs-store.js:1649) at setStateValue (ngxs-store.js:1770)

victos avatar Jul 31 '19 09:07 victos

@victos create issue with reproduce

splincode avatar Jul 31 '19 10:07 splincode

This error occurred when I get the property from getState and put it back within setState. Maybe this is not a bug. The property get from the getState is not a pure JavaScript object.

victos avatar Jul 31 '19 11:07 victos

I will not be able to help unless I see specific examples.

splincode avatar Jul 31 '19 13:07 splincode

Here's an example, https://stackblitz.com/edit/angular-jwqaif3?file=src/app/app.module.ts

victos avatar Jul 31 '19 14:07 victos

Sorry to emphase but It's a catastrophic bug. I'm losing a lot of time to make a workaround for this. Any advise would be welcome, thank.

dfa1234 avatar Aug 14 '19 13:08 dfa1234

Sorry to emphase but It's a catastrophic bug. I'm losing a lot of time to make a workaround for this. Any advise would be welcome, thank.

Maybe you can use the function isDraft to know if an object is a Proxy, and use function original to get the pure JavaScript object from the Proxy Here’s the doc of immer: https://github.com/immerjs/immer#extracting-the-original-object-from-a-proxied-instance

victos avatar Aug 14 '19 13:08 victos

Thank. I learned I need to learn more about Proxy :)

Anyway I finally found a workaround, before reading you comment. I presume original from immer is better than my solution, which is simply to make a deep clone (using JSON parse/ stringify)

  @Action(OpenCategory)
  @ImmutableContext()
  openCategory({setState, getState}: StateContext<CatalogState>, {categoryToOpen}: OpenCategory) {

    let state: CatalogState = cloneDeep(getState());

    state.current.page = 0;
    state.current.product = null;

   // until now, we are cool.`setState` would work:
   // setState(s => state);

   // But now this line would error my setState:
   // state.current.category = categoryToOpen;

   // `categoryToOpen` is indeed a proxy
   // So I simply had to make a clone to make is work (cloneDeep is just a JSON parse /stringify)
    state.current.category = cloneDeep(categoryToOpen);

   // Edit: just tested and indeed, using original work like  charm
   state.current.category = original(categoryToOpen);
   
   //working
   setState(s => state);

}

Any comment on the above code is more than welcome

dfa1234 avatar Aug 14 '19 14:08 dfa1234

@dfa1234 I would not use JSON serialization if you have a complex object with functions etc. You you can loose properties, like Function and Infinity and you will also lose properties with undefined values.

Only use it if you have a simple object with only values.

xtreemrage avatar Nov 05 '19 14:11 xtreemrage