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

reopen: TypeError: Cannot assign to read only property 'tView' of object '[object Object]' #2404

Closed
pburkindine opened this issue Feb 22, 2020 · 21 comments · Fixed by #2491
Closed

Comments

@pburkindine
Copy link

pburkindine commented Feb 22, 2020

revisiting: #2109

@brandonroberts @AndrewKushnir I am still experiencing this error in A9. I have tried disabling both strictState and strictAction, and also upgrading to [email protected]

Our use case is this: various nx modules are passing a Type through state to the app.component, where the component is factoried into a MatSidenavContainer. (not routing-related but same error)

I also tried passing the factory instead and received a similar error.

Please let me know what information I can provide.

@pburkindine
Copy link
Author

(I am attempting to work around this with a service, but feel the use case is important either way)

@pburkindine
Copy link
Author

A small bus service served in place of ngrx here; less than ideal but until freeze is updated to work with ivy this worked

@brandonroberts
Copy link
Member

@pburkindine we fixed the issue of actions coming from NgRx libraries being filtered from immutability checks, but other actions are not, which is probably what you're seeing here.

@timdeschryver
Copy link
Member

@pburkindine did you had the immutability checks on or off in the previous version of NgRx?

@pburkindine
Copy link
Author

@timdeschryver They've been turned on since we upgraded to ngrx 8 along with A8 last year

@rkkp1023
Copy link

rkkp1023 commented Mar 3, 2020

Facing Same Issue @timdeschryver
Any Solution For this

@timdeschryver
Copy link
Member

Can we have a reproduction of this behavior?

@rkkp1023
Copy link

rkkp1023 commented Mar 3, 2020

@timdeschryver I resolved the issue . In my case, this is because of ngrx-Store-freeze.
after removing ngrx-store-freeze it works. Hope This Works for all.

@pburkindine
Copy link
Author

@timdeschryver
Copy link
Member

The problem is that a component is being dispatched as meta data on the action.
If I've understood it correctly, Ivy will mutate the component - which is causing errors with the immutability checks.

I'm just not sure if we should change this behavior.
For example, in the repro I would rather prefer a different type, e.g. a string, instead of the component itself.

@curiouscod3
Copy link

This can be happend when using "[(ngModel)]"

@timdeschryver
Copy link
Member

@curiouscod3 the example you posted does indeed throw an error but it's unrelated to this issue.
It throws an error because it's using two-way binding, which is modifying the state.

@geo242
Copy link

geo242 commented Apr 2, 2020

This error happens to me in v8 and v9 when using the StoreRouterConnectingModule and strictStateImmutability set to true. In v8 I can get rid of the error with RouterState.Minimal, but not in v9.

Is this a known issue, or do I need to change something? Any tips to diagnose this would be greatly appreciated. The stack trace doesn't seem to help much.

Update: I was storing a list of the last x number of actions in my state in a demo app, which included router actions. I have now filtered out the ROUTER_NAVIGATION action and that seems to solve the issue in v8 and v9. My demo app doesn't exercise all the different navigation actions, so it might need to include more.

It sure would be helpful if there was more debugging info in the error so you could quickly find what needs to be changed to keep from violating the immutability checks.

@pburkindine
Copy link
Author

pburkindine commented Apr 4, 2020

The problem is that a component is being dispatched as meta data on the action.
If I've understood it correctly, Ivy will mutate the component - which is causing errors with the immutability checks.

I'm just not sure if we should change this behavior.
For example, in the repro I would rather prefer a different type, e.g. a string, instead of the component itself.

Hi, @timdeschryver

I generally understand this response, although in our case passing a component was much less problematic than passing a string. (Passing a string would require us at a minimum to maintain a map of loadable components that we didn't have to keep up with before; this is dozens of components and changing all the time, etc etc.) But I'm fine with doing the same thing with a bus service.

I guess my only ask would be that ngrx enforce this restriction or add helpful error messaging as figuring this out was pretty tough and it's a common-enough scenario

Thanks,
Pete

@brandonroberts
Copy link
Member

Hi @pburkindine,

From what I can tell, the issues come in when you're dispatching an action not owned by an NgRx library that contains a component, with immutability checks enabled. I see a couple of potential options here.

  • We know the properties that are attached on components compiled with Ivy, so we could exclude those from being frozen internally. Assuming these don't change, this would solve most cases.
  • We could add some sort of exclude function for runtimeChecks, where the developer provides a boolean whether the provided action should be checked.

Thoughts?

cc: @timdeschryver

@timdeschryver
Copy link
Member

@brandonroberts I was hoping we shouldn't have to check for ivy components.
But it seems like we have no choice, I'm not a fan of the exclude function.
Either you're using them, or not, because otherwise I'm afraid it might lead to weird behavior while replaying/rehydrating the state.

@brandonroberts
Copy link
Member

@timdeschryver I agree with your hesitation with the exclude function. I agree that passing components through the store if you're also needed to replay/rehydrate the state will cause weird behavior. I also think Ivy components are an exception to the rule as they are provided by the upstream framework. If its outside of that use case, I would recommend using a different mechanism to pass components around.

@pburkindine
Copy link
Author

pburkindine commented Apr 13, 2020

Hi @brandonroberts,

Thanks for the reply! The first option seems reasonable to me as it will be totally transparent versus a flag, hard to think of a scenario where someone would be passing a class through state post-Ivy where this wouldn't be "vanilla".

In a more general way it's hard for me to think of a reason to make a class immutable in state (in modern TS land, why would you be messing with the class itself?). (I guess theoretically someone would mutate a prototype and screw up another consumer? Would the store prevent that?). So you could make the argument that references to classes should be totally exempt from immutability in general (from my 20,000ft not-involved POV).

@smurugavels
Copy link

Hello.
I am here from angular/angular#34993 and #2109
We have angular: 9.1.4 and ngrx : 9.1.2. Yet I had to turn off runtime checks to suppress the error. Our app components 98% of them are loaded as dynamic components.

Q: I wonder how to get strictStateImmutability runtime check benefits with Ivy?

At this time our app has runtime check OFF

Ref: https://ngrx.io/guide/store/configuration/runtime-checks

@crisarji
Copy link

Hi!,
Not sure how I ended up in this thread, but fortunately, this last comment from @smurugavels is exactly the fix to my issue.

Currently working in a ngrx-firebase project, dependencies like this:

...
...
"@angular/core": "~9.1.9",
"@angular/fire": "~5.4.2",
"firebase": "~7.9.3",
...
...

Getting these error as soon as a valid user logs in:

ERROR TypeError: Cannot read property 'maxUploadRetryTime' of undefined
    at Object.get [as maxUploadRetryTime]

and

Unhandled Promise rejection: Cannot assign to read only property 'name' of object 'Error: Fetching auth token failed: Cannot add property 0, object is not extensible' ; Zone: <root> ; Task: Promise.then ; Value: TypeError: Cannot assign to read only property 'name' of object 'Error: Fetching auth token failed: Cannot add property 0, object is not extensible'

The only way to get rip off these above is to turn off runtime checks as indicated here https://ngrx.io/guide/store/configuration/runtime-checks

@GreedyA1
Copy link

I have the same issue. I am also using angularfire. I did have the issue with saving User object in store. The way I solved it was to get specific properties from User returned by firebase api and write them to my User object. and only afterwards pass it to success action. Now I got the same error when I am trying to save AngularFireUploadTask-s in store. I decided to disable the runetime-checks, but I do want to avoid it. any solutions to this issue? I don't want to copy and pick properties from the AngularFireUploadTask object, similarly to what I did with User object, but that might solve the issue once again.

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

Successfully merging a pull request may close this issue.

9 participants