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

Created on 22 Feb 2020  路  21Comments  路  Source: ngrx/platform

revisiting: https://github.com/ngrx/platform/issues/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.

Store question

Most helpful comment

@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.

All 21 comments

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

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

@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.

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

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

Facing Same Issue @timdeschryver
Any Solution For this

Can we have a reproduction of this behavior?

@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.

@timdeschryver @brandonroberts I created a repro:

https://github.com/pburkindine/ngrx-tview-issue

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.

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

@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.

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.

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

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

@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.

@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.

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).

Hello.
I am here from https://github.com/angular/angular/issues/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

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

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.

Was this page helpful?
0 / 5 - 0 ratings