Reputation: 699
I want to save dynamic component to @ngrx/store. but I get ERROR TypeError: Cannot freeze when dispatching an action from my component.
I referred to this page Why do I get "TypeEror: Cannot freeze"?. and I copied component object. but still I get this error.
Component :
ngOnInit() {
this.contents$ = this.store.pipe(select(fromContents.getContents));
}
addPhotoChild() {
const componentFactory = this.CFR.resolveComponentFactory(
PhotoChildComponent
);
const componentRef: ComponentRef<PhotoChildComponent> =
this.VCR.createComponent(componentFactory);
const currentComponent = componentRef.instance;
currentComponent.selfRef = currentComponent;
currentComponent.index = this.index++;
currentComponent.userId = this.user.id;
currentComponent.uploadedPhoto.subscribe(val => {
this.photo = val;
const cloneComp = Object.assign({}, currentComponent);
this.store.dispatch(new SaveContents({ comp: cloneComp }));
});
currentComponent.compInteraction = this;
this.componentsReferences.push(componentRef);
}
Action:
export class SaveContents implements Action {
readonly type = ContentsActionTypes.SAVE_CONTENTS;
constructor(public payload: { comp: PhotoChildComponent | GmapChildComponent }) {}
}
export class LoadContents implements Action {
readonly type = ContentsActionTypes.LOAD_CONTENTS;
}
Reducer:
export interface ContentsState extends EntityState<PhotoChildComponent | GmapChildComponent> {
allContentsLoaded: boolean;
}
export const adapter: EntityAdapter<PhotoChildComponent | GmapChildComponent> =
createEntityAdapter<PhotoChildComponent | GmapChildComponent>();
export const initialContentsState: ContentsState = adapter.getInitialState({
ids: [],
entities: {},
allContentsLoaded: false
});
export function contentsReducer(state = initialContentsState, action: ContentsActions) {
switch (action.type) {
case ContentsActionTypes.LOAD_CONTENTS: {
return {
...state,
allContentsLoaded: true
};
}
case ContentsActionTypes.SAVE_CONTENTS: {
return adapter.addOne(action.payload.comp, state);
}
default:
return state;
}
}
selector:
export const selectContentsState = createFeatureSelector<ContentsState>('contents');
export const getContents = createSelector(
selectContentsState,
adapter.getSelectors().selectAll
);
Upvotes: 2
Views: 1332
Reputation: 2999
Don't save the instance of the component in ngRx store.
Create a service, that will keep the Set of the components you want to render dynamically. Set the component name as key, and component factory as value.
In the store, you can keep the name of the component, and use it to retrieve the component from the service you have created.
Upvotes: 1