Last active
April 13, 2024 18:24
-
-
Save rhutchison/7a6ad7ee90fbce88548ef92d7ff2f506 to your computer and use it in GitHub Desktop.
ngxr signalStore
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Injectable() | |
export class ProductsSearchState extends searchStore<Product>() { | |
private readonly api = inject(ProductsService); | |
search(criteria: SearchCriteria) { | |
console.log(criteria); | |
// this.api.query(criteria); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { computed, Injectable } from '@angular/core'; | |
import { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop'; | |
import { signalStore, signalStoreFeature, withState } from '@ngrx/signals'; | |
import { isEqual } from 'lodash-es'; | |
import { distinctUntilChanged } from 'rxjs'; | |
type SearchCriteria = { | |
from: number; | |
term: string; | |
} | |
export interface SearchResult<T> { | |
hits?: T[]; | |
total?: number; | |
} | |
export function withSearchState<T>() { | |
return signalStoreFeature( | |
withState(() => ({ | |
from: 1, | |
term: '', | |
result: {} as SearchResult<T>, | |
})) | |
); | |
} | |
export function searchStore<T>() { | |
const SignalStore = signalStore(withSearchState<T>()); | |
@Injectable() | |
abstract class SearchSignalStore extends SignalStore { | |
constructor() { | |
super(); | |
this.#initSearch(); | |
} | |
abstract search(criteria: SearchCriteria): void; | |
searchState = computed<SearchCriteria>(() => ({ | |
term: this.term() ?? '', | |
from: this.from() ?? 1, | |
})); | |
#initSearch() { | |
toObservable(this.searchState) | |
.pipe( | |
distinctUntilChanged<SearchCriteria>(isEqual), | |
takeUntilDestroyed() | |
) | |
.subscribe({ | |
next: (criteria) => { | |
this.search(criteria); | |
}, | |
}); | |
} | |
} | |
return SearchSignalStore; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment