https://github.com/simmor-store/angular-simmor-examples
An example of how to use simmor with Angular
https://github.com/simmor-store/angular-simmor-examples
angular immer rxjs simmor
Last synced: about 2 months ago
JSON representation
An example of how to use simmor with Angular
- Host: GitHub
- URL: https://github.com/simmor-store/angular-simmor-examples
- Owner: simmor-store
- Created: 2019-09-30T16:38:49.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2023-01-07T10:15:00.000Z (over 3 years ago)
- Last Synced: 2025-03-23T05:11:14.531Z (over 1 year ago)
- Topics: angular, immer, rxjs, simmor
- Language: TypeScript
- Homepage:
- Size: 1.78 MB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 27
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
Simmor is a simple immutable boilerplate-free framework-agnostic store.
[https://github.com/simmor-store/simmor](https://github.com/simmor-store/simmor)
This repository is an example of how to use it with Angular.
# Install
```
npm install simmor
```
Simmor uses `rxjs` internally so it doesn't require additional packages and can be used with `async` pipe.
# Store example
Assume, we have this simple service
```ts
@Injectable({providedIn: 'root'})
export class CounterService {
getValue() {
return of(123).pipe(delay(300));
}
}
```
And we want to create a store with state like this
```ts
export interface CounterState {
value: number;
}
const initialState: CounterState = {
value: 0
}
```
We can define a store class. State can be modified throw `draft` field. Simmor uses [immer](https://github.com/immerjs/immer) that can update immutable state by mutating it.
```ts
@Injectable({providedIn: 'root'})
export class CounterStore extends ReducerStore {
constructor(private counterService: CounterService) {
super(initialState, {
middlewares: [createLocalStorageMiddleware('counter')]
});
}
increase() {
this.draft.value += 1;
}
decrease() {
const newValue = this.draft.value - 1
if (newValue >= 0) {
this.draft.value = newValue;
}
}
setValue(value: number) {
this.draft.value = value;
}
setValueAsync() {
this.counterService.getValue().subscribe(value => {
this.setValue(value);
});
}
}
```
Now we can use our store in a component like this
```ts
@Component({
selector: 'app-counter',
templateUrl: './counter.component.html',
styleUrls: ['./counter.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class CounterComponent implements OnInit {
constructor(private store: CounterStore) { }
ngOnInit() { }
}
```
```html
{{state.value}}
+
-
Reset
Set value async
```
# Middlewares
Simmor supports middlewares. Here an example of middleware that saves state to localStorage.
```ts
export function createLocalStorageMiddleware(key: string): Middleware {
return next => action => {
const newState = next(action)
if (action.methodName === "constructor") {
const savedState = localStorage.getItem(key)
if (savedState) {
return JSON.parse(savedState)
}
}
localStorage.setItem(key, JSON.stringify(newState))
return newState
}
}
```
We can pass middlewares in the constructor of the store and our component can now save its state between sessions.
```ts
@Injectable({providedIn: 'root'})
export class CounterStore extends ReducerStore {
constructor(private counterService: CounterService) {
super(initialState, {
middlewares: [createLocalStorageMiddleware('counter')]
});
}
}
```