-
Notifications
You must be signed in to change notification settings - Fork 10
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
Update to NgRx 4 #17
Comments
To be a bit more precise:
Steps to reproduce:
|
@DorianGrey
|
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 Oh, and just for completeness: The above is a variant of this library and the underlying Just hope anyone has got a better idea than this hack, although I fear there are not that many solutions for this problem ... |
when will suport for ngrx v4 land? |
I think that we just have to wait for router-state serializer to be done. Once in, it should fix the following issue (which is pretty much the issue we are having here): If you leave the router-store out of store, storeFreeze should work. |
Note: we're having the same problem, even though we're not using ngrx/router-store. |
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. |
Besides that, I'm receiving an npm WARN [email protected] requires a peer of @ngrx/store@^2.2.1 but none was installed. |
Hey guys, |
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 |
@tsm91, perhaps you can start a fundraiser to resolve this issue? Make it worth your time. |
@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. |
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
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.
That already happend - the problem originially described here was cause by
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. |
Version |
Well done for the great work @brandonroberts! Just one remaining issue: there is still a conflict with @ngrx/router-store. The |
@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 |
@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. |
@colinskow no problem, docs updated in ngrx/platform#426 |
I also added some docs in the README about |
Hmmm... for me issue is back after updating to NgRx 5.0, my ngrx-store-freeze version is 0.2.1 |
Issue still exists on ngrx 6. |
I am getting the same issue when using dispatch action, i cannot mutate property in my component to be pass inside dispatch. |
It appears that ngrx-store-freeze is incompatible with NgRx 4.
The text was updated successfully, but these errors were encountered: