From a39ef774b9832a611138fabc8b699c5288969199 Mon Sep 17 00:00:00 2001 From: Justin Baur <19896123+justindbaur@users.noreply.github.com> Date: Mon, 16 Oct 2023 08:51:19 -0400 Subject: [PATCH] Use a Fake Default Value to seed BehaviorSubject - Filter out the emission of the fake value --- .../src/platform/state/default-user-state.ts | 32 +++++++++++-------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/libs/common/src/platform/state/default-user-state.ts b/libs/common/src/platform/state/default-user-state.ts index 87d778971d3..1882bb4fc5b 100644 --- a/libs/common/src/platform/state/default-user-state.ts +++ b/libs/common/src/platform/state/default-user-state.ts @@ -28,6 +28,8 @@ import { DerivedUserState } from "./derived-user-state"; import { KeyDefinition } from "./key-definition"; import { StorageLocation } from "./state-definition"; +const FAKE_DEFAULT = Symbol.for("fakeDefault"); + // TODO: Update storage services to emit when any key is updated // Then listen to that observable here to emit on `state$` when the `formattedKey$` // is reported updated by the storage service; @@ -37,7 +39,9 @@ export class DefaultUserState implements UserState { private formattedKey$: Observable; private chosenStorageLocation: AbstractStorageService; - protected stateSubject: BehaviorSubject = new BehaviorSubject(null); + protected stateSubject: BehaviorSubject = new BehaviorSubject< + T | typeof FAKE_DEFAULT + >(FAKE_DEFAULT); private stateSubject$ = this.stateSubject.asObservable(); state$: Observable; @@ -104,21 +108,17 @@ export class DefaultUserState implements UserState { }, }) ); - }); + }) + // I fake the generic here because I am filtering out the other union type + // and this makes it so that typescript understands the true type + .pipe(filter((value) => value != FAKE_DEFAULT)); } async update(configureState: (state: T) => T): Promise { const key = await this.createKey(); - if (key == null) { - throw new Error("Attempting to active user state, when no user is active."); - } - const currentState = this.seededInitial - ? this.stateSubject.getValue() - : await this.seedInitial(key); - + const currentState = await this.getGuaranteedState(key); const newState = configureState(currentState); - - await this.saveToStorage(await this.createKey(), newState); + await this.saveToStorage(key, newState); return newState; } @@ -160,10 +160,16 @@ export class DefaultUserState implements UserState { return formattedKey; } + protected async getGuaranteedState(key: string) { + const currentValue = this.stateSubject.getValue(); + return currentValue == FAKE_DEFAULT ? await this.seedInitial(key) : currentValue; + } + private async seedInitial(key: string): Promise { const data = await this.chosenStorageLocation.get>(key); - this.seededInitial = true; - return this.keyDefinition.deserializer(data); + const serializedData = this.keyDefinition.deserializer(data); + this.stateSubject.next(serializedData); + return serializedData; } private chooseStorage(storageLocation: StorageLocation): AbstractStorageService {