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

feat(component-store): add patchState method #2788

Merged
merged 2 commits into from
Nov 23, 2020

Conversation

markostanimirovic
Copy link
Member

PR Checklist

Please check if your PR fulfills the following requirements:

PR Type

What kind of change does this PR introduce?

[ ] Bugfix
[x] Feature
[ ] Code style update (formatting, local variables)
[ ] Refactoring (no functional changes, no api changes)
[ ] Build related changes
[ ] CI related changes
[ ] Documentation content changes
[ ] Other... Please describe:

What is the current behavior?

// case 1
this.moviesStore.setState(state => ({
  ...state,
  movies,
}));

// case 2
this.moviesStore.setState(state => ({
  ...state,
  movies: [...state.movies, movie],
}));

Closes #2786

What is the new behavior?

// case 1
this.moviesStore.patchState({ movies });

// case 2
this.moviesStore.patchState(state => ({
  movies: [...state.movies, movie],
}));

Does this PR introduce a breaking change?

[ ] Yes
[x] No

@ngrxbot
Copy link
Collaborator

ngrxbot commented Nov 17, 2020

Preview docs changes for 2c2fc55 at https://previews.ngrx.io/pr2788-2c2fc556/

Copy link
Member

@timdeschryver timdeschryver left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It keeps surprising (in a good way) me that this code "is so simple" 👍

it(
'with a value based on the previous state',
marbles((m) => {
componentStore.patchState(() => ({ value2: { foo: 'fooBar' } }));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this test use the current state to build a new state?

e.g.

Suggested change
componentStore.patchState(() => ({ value2: { foo: 'fooBar' } }));
componentStore.patchState((state) => ({ value2: { foo: state.value2.foo + "2" } }));

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure 🙂

Copy link
Member

@alex-okrushko alex-okrushko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this 👍

patchState(
partialStateOrUpdaterFn: Partial<T> | ((state: T) => Partial<T>)
): void {
if (!this.isInitialized) {
Copy link
Member

@alex-okrushko alex-okrushko Nov 17, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updater (and setState that calls the updater) does this check, so it's not needed here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

throw new Error(this.notInitializedErrorMessage);
}

const updaterFn = (state: T) => ({
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a few suggestions:

  1. We can use this.setState here
  2. Let's extract and evaluate patchedState separately for readability purposes.
Suggested change
const updaterFn = (state: T) => ({
this.setState((state) => {
const patchedState = (typeof partialStateOrUpdaterFn === 'function')
? partialStateOrUpdaterFn(state)
: partialStateOrUpdaterFn;
return {
...state,
...patchedState, // 👈 comes after `state` to override the properties
};
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@alex-okrushko alex-okrushko merged commit ecedadb into ngrx:master Nov 23, 2020
brandonroberts pushed a commit that referenced this pull request Nov 25, 2020
* feat(component-store): add patchState method

* use setState in patchState; remove isInitialized check; improve test case with callback
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add patchState method to the ComponentStore
5 participants