Skip to content

Commit

Permalink
fix(persist-state): implementation of StateStorage should work with c…
Browse files Browse the repository at this point in the history
…lass instances (#271)

Since we were using destructuring to get the methods "getItem" and "setItem",
if `this` were used we would get an undefined error, because `this` is undefined.
This change simply removes the destructuring of the methods

Co-authored-by: stLmpp <[email protected]>
  • Loading branch information
stLmpp and stLmpp committed May 26, 2022
1 parent 5402ad9 commit 822f411
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 17 deletions.
41 changes: 39 additions & 2 deletions packages/persist-state/src/lib/persist-state.spec.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import { Observable, of } from 'rxjs';
import { map } from 'rxjs/operators';
import { addEntities } from '@ngneat/elf-entities';
import {
addEntities,
deleteEntities,
updateEntities,
} from '@ngneat/elf-entities';
import { createEntitiesStore, createTodo } from '@ngneat/elf-mocks';
import { StateStorage } from './storage';
import { Async, StateStorage } from './storage';
import { persistState } from './persist-state';

describe('persist state', () => {
Expand Down Expand Up @@ -90,4 +94,37 @@ describe('persist state', () => {

expect(subscriptions.size).toBe(0);
});

it('should work with class instances', () => {
class CustomStateStorage implements StateStorage {
private readonly _storage: Record<string, string> = {};

getItem<T extends Record<string, any>>(
key: string
): Async<T | undefined> {
const value = this._storage[key];
return Promise.resolve(value && JSON.parse(value));
}

removeItem(key: string): Async<boolean> {
delete this._storage[key];
return Promise.resolve(true);
}

setItem(key: string, value: Record<string, any>): Async<boolean> {
this._storage[key] = JSON.stringify(value);
return Promise.resolve(true);
}
}
const customStateStorage = new CustomStateStorage();
const store = createEntitiesStore();
expect(() => {
persistState(store, { storage: customStateStorage });
store.update(addEntities(createTodo(1)));
store.update(updateEntities(1, { title: 'new-title' }));
store.update(deleteEntities(1));
}).not.toThrowError(
new TypeError(`Cannot read properties of undefined (reading '_storage')`)
);
});
});
30 changes: 15 additions & 15 deletions packages/persist-state/src/lib/persist-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,29 +32,29 @@ export function persistState<S extends Store>(store: S, options: Options<S>) {
};
}

const { setItem, getItem } = options.storage;
const { storage } = options;
const initialized = new ReplaySubject<boolean>(1);

const loadFromStorageSubscription = from(getItem(merged.key!)).subscribe(
(value) => {
if (value) {
store.update((state) => {
return merged.preStoreInit!({
...state,
...value,
});
const loadFromStorageSubscription = from(
storage.getItem(merged.key!)
).subscribe((value) => {
if (value) {
store.update((state) => {
return merged.preStoreInit!({
...state,
...value,
});
}

initialized.next(true);
initialized.complete();
});
}
);

initialized.next(true);
initialized.complete();
});

const saveToStorageSubscription = merged.source!(store)
.pipe(
skip(1),
switchMap((value) => setItem(merged.key!, value))
switchMap((value) => storage.setItem(merged.key!, value))
)
.subscribe();

Expand Down

0 comments on commit 822f411

Please sign in to comment.