Skip to content

Commit

Permalink
adjust according to the review from Tim
Browse files Browse the repository at this point in the history
  • Loading branch information
Alex Okrushko committed Jul 12, 2020
1 parent d3c9b37 commit 0d67ea2
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 12 deletions.
73 changes: 65 additions & 8 deletions modules/component-store/spec/component-store.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,24 @@ describe('Component Store', () => {
const componentStore = new ComponentStore();

m.expect(componentStore.state$).toBeObservable(
m.hot('#', {}, new Error('ComponentStore has not been initialized'))
m.hot(
'#',
{},
new Error(
'ComponentStore has not been initialized yet. ' +
'Please make sure it is initialized before updating/getting.'
)
)
);

expect(() => {
componentStore.setState(() => ({ setState: 'new state' }));
}).toThrow(new Error('ComponentStore has not been initialized'));
}).toThrow(
new Error(
'ComponentStore has not been initialized yet. ' +
'Please make sure it is initialized before updating/getting.'
)
);
})
);

Expand All @@ -77,14 +89,26 @@ describe('Component Store', () => {
const componentStore = new ComponentStore();

m.expect(componentStore.state$).toBeObservable(
m.hot('#', {}, new Error('ComponentStore has not been initialized'))
m.hot(
'#',
{},
new Error(
'ComponentStore has not been initialized yet. ' +
'Please make sure it is initialized before updating/getting.'
)
)
);

expect(() => {
componentStore.updater((state, value: object) => value)({
updater: 'new state',
});
}).toThrow(new Error('ComponentStore has not been initialized'));
}).toThrow(
new Error(
'ComponentStore has not been initialized yet. ' +
'Please make sure it is initialized before updating/getting.'
)
);
})
);

Expand All @@ -98,14 +122,26 @@ describe('Component Store', () => {
});

m.expect(componentStore.state$).toBeObservable(
m.hot('#', {}, new Error('ComponentStore has not been initialized'))
m.hot(
'#',
{},
new Error(
'ComponentStore has not been initialized yet. ' +
'Please make sure it is initialized before updating/getting.'
)
)
);

expect(() => {
componentStore.updater<object>((state, value) => value)(
syncronousObservable$
);
}).toThrow(new Error('ComponentStore has not been initialized'));
}).toThrow(
new Error(
'ComponentStore has not been initialized yet. ' +
'Please make sure it is initialized before updating/getting.'
)
);
})
);

Expand All @@ -122,7 +158,14 @@ describe('Component Store', () => {
let subscription: Subscription | undefined;

m.expect(componentStore.state$).toBeObservable(
m.hot('-#', {}, new Error('ComponentStore has not been initialized'))
m.hot(
'-#',
{},
new Error(
'ComponentStore has not been initialized yet. ' +
'Please make sure it is initialized before updating/getting.'
)
)
);

expect(() => {
Expand Down Expand Up @@ -1238,7 +1281,10 @@ describe('Component Store', () => {
expect(() => {
componentStore.get((state) => state.value);
}).toThrow(
new Error('ExposedGetComponentStore has not been initialized')
new Error(
'ExposedGetComponentStore has not been initialized yet. ' +
'Please make sure it is initialized before updating/getting.'
)
);
});

Expand All @@ -1261,5 +1307,16 @@ describe('Component Store', () => {

expect(componentStore.get((state) => state.value)).toBe('updated');
});

it('provides the entire state when projector fn is not provided', () => {
componentStore = new ExposedGetComponentStore();
componentStore.setState({ value: 'init' });

expect(componentStore.get()).toEqual({ value: 'init' });

componentStore.updater((state, value: string) => ({ value }))('updated');

expect(componentStore.get()).toEqual({ value: 'updated' });
});
});
});
13 changes: 9 additions & 4 deletions modules/component-store/src/component-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ export class ComponentStore<T extends object> implements OnDestroy {

private readonly stateSubject$ = new ReplaySubject<T>(1);
private isInitialized = false;
private notInitializedErrorMessage = `${this.constructor.name} has not been initialized`;
private notInitializedErrorMessage =
`${this.constructor.name} has not been initialized yet. ` +
`Please make sure it is initialized before updating/getting.`;
// Needs to be after destroy$ is declared because it's used in select.
readonly state$: Observable<T> = this.select((s) => s);

Expand Down Expand Up @@ -152,13 +154,16 @@ export class ComponentStore<T extends object> implements OnDestroy {
}
}

protected get<R>(projector: (s: T) => R): R {
protected get(): T;
protected get<R>(projector: (s: T) => R): R;
protected get<R>(projector?: (s: T) => R): R | T {
if (!this.isInitialized) {
throw new Error(this.notInitializedErrorMessage);
}
let value: R;
let value: R | T;

this.stateSubject$.pipe(take(1)).subscribe((state) => {
value = projector(state);
value = projector ? projector(state) : state;
});
return value!;
}
Expand Down

0 comments on commit 0d67ea2

Please sign in to comment.