Git Product home page Git Product logo

Comments (22)

timbru31 avatar timbru31 commented on May 31, 2024 12

Besides that, I'm receiving an UNMET PEER DEPENDENCY @ngrx/[email protected], because ngrx-store-freeze defines v2.2.1 of @ngrx/store

npm WARN [email protected] requires a peer of @ngrx/store@^2.2.1 but none was installed.

from ngrx-store-freeze.

dojchek avatar dojchek commented on May 31, 2024 10

Hey guys,
Any update on this one?

from ngrx-store-freeze.

DorianGrey avatar DorianGrey commented on May 31, 2024 4

To be a bit more precise:
I've seen this issue as well while updating my template to ngrx4. It seems that parameters accessed by zone.js get freezed as well. At least that's what the browser console mentions:

TypeError: Cannot assign to read only property 'microTask' of object '[object Object]'
    at ZoneDelegate._updateTaskCount (polyfills.dll.js:5603)
    at Zone._updateTaskCount (polyfills.dll.js:5438)
    at Zone.runTask (polyfills.dll.js:5358)
    at drainMicroTaskQueue (polyfills.dll.js:5745)
    at <anonymous>

Uncaught TypeError: Cannot assign to read only property 'macroTask' of object '[object Object]'
    at ZoneDelegate._updateTaskCount (http://localhost:9987/polyfills.dll.js:5603:37)
    at Zone._updateTaskCount (http://localhost:9987/polyfills.dll.js:5438:34)
    at Zone.scheduleTask (http://localhost:9987/polyfills.dll.js:5397:22)
    at Zone.scheduleMacroTask (http://localhost:9987/polyfills.dll.js:5408:25)
    at http://localhost:9987/polyfills.dll.js:7009:33
    at proto.(anonymous function) (http://localhost:9987/polyfills.dll.js:6371:20)
    at XHRLocalObject.AbstractXHRObject (http://localhost:9987/polyfills.dll.js:4184:3)
    at new XHRLocalObject (http://localhost:9987/polyfills.dll.js:2208:13)
    at new InfoAjax (http://localhost:9987/polyfills.dll.js:4779:13)
    at Function.InfoReceiver._getReceiver (http://localhost:9987/polyfills.dll.js:11380:12)

Uncaught Error: macroTask 'setTimeout': can not transition to 'running', expecting state 'scheduled', was 'scheduling'.
    at ZoneTask._transitionTo (polyfills.dll.js:5682)
    at Zone.runTask (polyfills.dll.js:5331)
    at ZoneTask.invokeTask (polyfills.dll.js:5648)
    at ZoneTask.invoke (polyfills.dll.js:5637)
    at timer (polyfills.dll.js:6973)

Steps to reproduce:

from ngrx-store-freeze.

dojchek avatar dojchek commented on May 31, 2024 4

@DorianGrey
I'm getting the same exception.. All I do is simply provide 'storeFreeze' as meta-reducer:

StoreModule.forRoot(reducers, {
      metaReducers: [storeFreeze]
    }),

from ngrx-store-freeze.

zakhenry avatar zakhenry commented on May 31, 2024 4

@colinskow you should consider using a custom serializer with the router store as the router state has huge performance impact on ngrx due to the default serialized object. This was the cause of the issue with the devtools bogging down with performance. See https://github.com/ngrx/platform/blob/master/docs/router-store/api.md#custom-router-state-serializer

from ngrx-store-freeze.

brandonroberts avatar brandonroberts commented on May 31, 2024 1

Version 0.2.0 has been released with support for NgRx V4.x

from ngrx-store-freeze.

colinskow avatar colinskow commented on May 31, 2024 1

Well done for the great work @brandonroberts! Just one remaining issue: there is still a conflict with @ngrx/router-store. The router-store contains mutating objects. This needs to be excluded from the freeze, or router-store needs to be fixed to not contain mutating objects.

from ngrx-store-freeze.

colinskow avatar colinskow commented on May 31, 2024 1

@zakhenry thank you very much! It's now working perfectly. These instructions definitely need to be added to the docs because a lot of people are going to have this problem.

from ngrx-store-freeze.

DorianGrey avatar DorianGrey commented on May 31, 2024

Ok... I've debugged this a little bit, and it seems to have something to do with parameters added by @ngrx/router-store. These parameters may contain a router snapshot and additional linked data, and you may guess what happens when these get frozen.

Unfortunately, this means that not only some parameters of the state have to be skipped - even some dispatched actions have to be ignored completely.

I've hacked a solution for this, though I'm not that lucky with it:

import {Action, ActionReducer} from "@ngrx/store";

/**
 * A list of properties to ignore when deep-freezing.
 * Contains arguments that must not be modified in strict mode in general
 * (caller, callee, arguments) plus the `router` argument, which is added by @ngrx/router-store.
 */
const propBlackList: string[] = ["caller", "callee", "arguments", "router"];

/**
 * A regular expression to match `action.type` against.
 * Some actions have to be ignored in general, since freezing
 * any parts of them has undesirable side-effects.
 */
const ignoreActionsRegex: RegExp = /^(ROUTER?_|@ngrx)/;

function deepFreeze(o: any): void {
  Object.freeze(o);
  const hasOwnProp = Object.prototype.hasOwnProperty;
  Object
    .getOwnPropertyNames(o)
    .filter(p => propBlackList.indexOf(p) === -1)
    .forEach(prop => {
    if (hasOwnProp.call(o, prop)
      && o[prop] !== null
      && (typeof o[prop] === "object" || typeof o[prop] === "function")
      && !Object.isFrozen(o[prop])) {
      deepFreeze(o[prop]);
    }
  });

  return o;
}

export function storeFreeze(reducer: ActionReducer<any>): ActionReducer<any> {
  return function (state: any, action: Action) {
    if (ignoreActionsRegex.test(action.type)) {
      return reducer(state, action);
    } else {
      state && deepFreeze(state);
      // Ignore null/undefined values.
      if ((action as any).payload != null) {
        deepFreeze((action as any).payload);
      }
      const nextState = reducer(state, action);
      nextState && deepFreeze(nextState);
      return nextState;
    }
  };
}

Primary concern is configuration - the router field is the name of the routerReducer entry in my state definition, and thus may vary for other users. Already tried some things, but AoT did not like any of them...

Oh, and just for completeness: The above is a variant of this library and the underlying deep-freeze-strict. Had to modify both of them to make things work for now.

Just hope anyone has got a better idea than this hack, although I fear there are not that many solutions for this problem ...

from ngrx-store-freeze.

lekhnath avatar lekhnath commented on May 31, 2024

when will suport for ngrx v4 land?

from ngrx-store-freeze.

dojchek avatar dojchek commented on May 31, 2024

I think that we just have to wait for router-state serializer to be done.
ngrx/platform#188 (comment)

Once in, it should fix the following issue (which is pretty much the issue we are having here):
ngrx/platform#104

If you leave the router-store out of store, storeFreeze should work.

from ngrx-store-freeze.

LMFinney avatar LMFinney commented on May 31, 2024

Note: we're having the same problem, even though we're not using ngrx/router-store.

from ngrx-store-freeze.

strizzaflex avatar strizzaflex commented on May 31, 2024

There is a workaround that was merged into trunk of router-store. It's in the nightly build and should be in the next release.

ngrx/platform#188 - pull

from ngrx-store-freeze.

aegyed91 avatar aegyed91 commented on May 31, 2024

can somebody issue a pull request please?

i no longer keep playing with angular && the ecosystem. but i feel bad about these issues, cmon guys make a pull request 💃

also looking for maintainer because of the reaons mentioned above

from ngrx-store-freeze.

sliekens avatar sliekens commented on May 31, 2024

@tsm91, perhaps you can start a fundraiser to resolve this issue? Make it worth your time.

from ngrx-store-freeze.

LMFinney avatar LMFinney commented on May 31, 2024

@DorianGrey's suggestion makes sense as a workaround for an individual, but I don't think it should be pulled into the library, because it would secretishly disable freezing for any properties named "caller", "callee", "arguments", or "router". There's bound to be other programmers that would use those names at some point.

Isn't the core message here that the @ngrx router is mutating things that it shouldn't? Perhaps this metareducer is doing the right thing, and @ngrx itself is what needs to change.

I mentioned above that my team was seeing the same problem, and I'm pretty sure it's because we use wrapped kendo jquery widgets, and those widgets mutate objects that they receive. So, it was either our mistake in sending the original store objects that should have been mutated to kendo, or kendo's mistake for assuming that it could mutate what it received. Either way, it wasn't the fault of ngrx-store-freeze.

from ngrx-store-freeze.

DorianGrey avatar DorianGrey commented on May 31, 2024

because it would secretishly disable freezing for any properties named "caller", "callee", "arguments", or "router".

Just a note - I did not add the first three of that list for no reason: These properties exist on a function object and everything that derives from it. In any code that runs in strict mode, accessing these parameters is restricted, and may throw errors when attempting to freeze them. That is why these parameters are skipped in the deep-freeze library used by this project as well (missed the isFunction check in my hack, of course).

Isn't the core message here that the @ngrx router is mutating things that it shouldn't?

The library itself does not mutate parts of the provided state. The problems described above refer to an issue about storing objects (here: from zone.js) that have to be mutatable from outside, and thus cannot be frozen.

Perhaps this metareducer is doing the right thing, and @ngrx itself is what needs to change.

That already happend - the problem originially described here was cause by ngrx/router-store, which stores a router snapshot. However, that snapshot referenced a lot of stuff that cannot be frozen safely.
That's why the ability to provide a custom state serializer was introduced recently:
https://github.com/ngrx/platform/blob/master/docs/router-store/api.md#custom-router-state-serializer
By providing one, it is possible to only use a part of the snapshot, e.g. the route name and query parameters, thus skipping parameters that may not be frozen safely. The only "issue" that still remains is the warning about the mismatching peer dependency:
[email protected] requires a peer of @ngrx/store@^2.2.1 but none was installed.

So, it was either our mistake in sending the original store objects that should have been mutated to kendo, or kendo's mistake for assuming that it could mutate what it received.

The store content is intended to be immutable - it would not make sense to try to freeze the content explicitly if there is still code that attempts to mutate the objects it receives. So this sounds like a misuse in general, and not a problem of the store or the freeze meta reducer.

from ngrx-store-freeze.

zakhenry avatar zakhenry commented on May 31, 2024

@colinskow no problem, docs updated in ngrx/platform#426

from ngrx-store-freeze.

brandonroberts avatar brandonroberts commented on May 31, 2024

I also added some docs in the README about @ngrx/router-store via #21

from ngrx-store-freeze.

markoffden avatar markoffden commented on May 31, 2024

Hmmm... for me issue is back after updating to NgRx 5.0, my ngrx-store-freeze version is 0.2.1

from ngrx-store-freeze.

duartealexf avatar duartealexf commented on May 31, 2024

Issue still exists on ngrx 6.

from ngrx-store-freeze.

Frayion avatar Frayion commented on May 31, 2024

I am getting the same issue when using dispatch action, i cannot mutate property in my component to be pass inside dispatch.
ngrx 7 and ngrx-store-freeze 0.2.4

from ngrx-store-freeze.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.