Skip to content

Instantly share code, notes, and snippets.

@rhutchison
Last active April 13, 2024 18:24
Show Gist options
  • Save rhutchison/7a6ad7ee90fbce88548ef92d7ff2f506 to your computer and use it in GitHub Desktop.
Save rhutchison/7a6ad7ee90fbce88548ef92d7ff2f506 to your computer and use it in GitHub Desktop.
ngxr signalStore
@Injectable()
export class ProductsSearchState extends searchStore<Product>() {
private readonly api = inject(ProductsService);
search(criteria: SearchCriteria) {
console.log(criteria);
// this.api.query(criteria);
}
}
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