Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions apps/demo/src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@
<a mat-list-item routerLink="/immutable-state">withImmutableState</a>
<a mat-list-item routerLink="/feature-factory">withFeatureFactory</a>
<a mat-list-item routerLink="/conditional">withConditional</a>
<a mat-list-item routerLink="/mutation">withMutation</a>
<a mat-list-item routerLink="/rx-mutation">rxMutation (without Store)</a>
<a mat-list-item routerLink="/mutation-store">withMutation</a>
<a mat-list-item routerLink="/mutation-functions"
>mutations (without Store)</a
>
</mat-nav-list>
</mat-drawer>
<mat-drawer-content>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@
font-size: 0.9rem;
}

.section {
section {
margin: 2rem 0;
padding: 1.5rem;
border: 1px solid #e0e0e0;
border-radius: 8px;
background-color: #fafafa;
}

.section h2 {
section h2 {
margin-top: 0;
color: #333;
border-bottom: 2px solid #007acc;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ <h1>rxMutation + httpMutation (without Store)</h1>

<div class="counter">{{ counter() }}</div>

<div class="section">
<section>
<h2>Local Increment (rxMutation)</h2>
<ul>
<li>isPending: {{ isPending() }}</li>
Expand All @@ -13,16 +13,16 @@ <h2>Local Increment (rxMutation)</h2>
</ul>

<div>
<button (click)="incrementCounter()" [disabled]="isPending()">
<button type="button" (click)="incrementCounter()" [disabled]="isPending()">
@if (isPending()) { Incrementing... } @else { Increment by 1 }
</button>
<button (click)="incrementBy13()" [disabled]="isPending()">
<button type="button" (click)="incrementBy13()" [disabled]="isPending()">
@if (isPending()) { Incrementing... } @else { Increment by 13 }
</button>
</div>
</div>
</section>

<div class="section">
<section>
<h2>Send to Server (httpMutation)</h2>

<ul>
Expand All @@ -33,8 +33,12 @@ <h2>Send to Server (httpMutation)</h2>
</ul>

<div>
<button (click)="saveCounterToServer()" [disabled]="saveIsPending()">
<button
type="button"
(click)="saveCounterToServer()"
[disabled]="saveIsPending()"
>
@if (saveIsPending()) { Sending to Server... } @else { Send to Server }
</button>
</div>
</div>
</section>
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {
httpMutation,
rxMutation,
} from '@angular-architects/ngrx-toolkit';
import { CommonModule } from '@angular/common';
import { JsonPipe } from '@angular/common';
import { Component, computed, signal } from '@angular/core';
import { delay, Observable, of, throwError } from 'rxjs';

Expand All @@ -16,16 +16,13 @@ export type CounterResponse = {
json: { counter: number };
};

// TODO - rename this file to just be `mutations-functions-standalone` + class/selector etc??
// And then the other folder to "store"
// Or maybe put these all in one folder too while we are at it?
@Component({
selector: 'demo-counter-rx-mutation',
imports: [CommonModule],
templateUrl: './counter-rx-mutation.html',
styleUrl: './counter-rx-mutation.css',
selector: 'demo-counter-mutation-functions',
imports: [JsonPipe],
templateUrl: './counter-mutation-functions.html',
styleUrl: './counter-mutation-functions.css',
})
export class CounterRxMutation {
export class CounterRxMutationFunctions {
private counterSignal = signal(0);

private increment = rxMutation({
Expand All @@ -41,13 +38,13 @@ export class CounterRxMutation {
},
});

private saveToServer = httpMutation<Params, CounterResponse>({
request: (p) => ({
private saveToServer = httpMutation({
request: (p: Params) => ({
url: `https://httpbin.org/post`,
method: 'POST',
body: { counter: p.value },
headers: { 'Content-Type': 'application/json' },
}),
parse: (response) => response as CounterResponse,
onSuccess: (response) => {
console.log('Counter sent to server:', response);
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@
font-size: 0.9rem;
}

.section {
section {
margin: 2rem 0;
padding: 1.5rem;
border: 1px solid #e0e0e0;
border-radius: 8px;
background-color: #fafafa;
}

.section h2 {
section h2 {
margin-top: 0;
color: #333;
border-bottom: 2px solid #007acc;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ <h1>withMutations + HTTP</h1>

<div class="counter">{{ counter() }}</div>

<div class="section">
<section>
<h2>Local Increment</h2>
<ul>
<li>isPending: {{ isPending() }}</li>
Expand All @@ -11,13 +11,13 @@ <h2>Local Increment</h2>
</ul>

<div>
<button (click)="increment()" [disabled]="isPending()">
<button type="button" (click)="increment()" [disabled]="isPending()">
@if (isPending()) { Incrementing... } @else { Increment }
</button>
</div>
</div>
</section>

<div class="section">
<section>
<h2>Sending to Server</h2>

<ul>
Expand All @@ -28,8 +28,8 @@ <h2>Sending to Server</h2>
</ul>

<div>
<button (click)="saveToServer()" [disabled]="saveIsPending()">
<button type="button" (click)="saveToServer()" [disabled]="saveIsPending()">
@if (saveIsPending()) { Sending to Server... } @else { Sending to Server }
</button>
</div>
</div>
</section>
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { CommonModule } from '@angular/common';
import { JsonPipe } from '@angular/common';
import { Component, inject } from '@angular/core';
import { CounterStore } from './counter.store';

@Component({
selector: 'demo-counter-mutation',
imports: [CommonModule],
templateUrl: './counter-mutation.html',
styleUrl: './counter-mutation.css',
selector: 'demo-counter-mutation-store',
imports: [JsonPipe],
templateUrl: './counter-mutation-store.html',
styleUrl: './counter-mutation-store.css',
})
export class CounterMutation {
export class CounterMutationStore {
private store = inject(CounterStore);

protected counter = this.store.counter;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,13 @@ export const CounterStore = signalStore(
console.error('Error occurred:', error);
},
}),
saveToServer: httpMutation<void, CounterResponse>({
request: () => ({
saveToServer: httpMutation({
request: (_: void) => ({
url: `https://httpbin.org/post`,
method: 'POST',
body: { counter: store.counter() },
headers: { 'Content-Type': 'application/json' },
}),
onSuccess: (response) => {
onSuccess: (response: CounterResponse) => {
console.log('Counter sent to server:', response);
patchState(store, { lastResponse: response.json });
},
Expand All @@ -54,24 +53,26 @@ export const CounterStore = signalStore(
})),
);

// For demo purposes, helps ensures we fail on the first time we hit 7 or 13
let error = false;

function createSumObservable(a: number, b: number): Observable<number> {
return new Observable<number>((subscriber) => {
const result = a + b;

if ((result === 7 || result === 13) && !error) {
subscriber.error({ message: 'error due to bad luck!', result });
error = true;
} else {
subscriber.next(result);
error = false;
}
subscriber.complete();
});
}

/**
* @description return of(a + b)
*/
function calcSum(a: number, b: number): Observable<number> {
// return of(a + b);
function createSumObservable(a: number, b: number): Observable<number> {
return new Observable<number>((subscriber) => {
const result = a + b;

if ((result === 7 || result === 13) && !error) {
subscriber.error({ message: 'error due to bad luck!', result });
error = true;
} else {
subscriber.next(result);
error = false;
}
subscriber.complete();
});
}
return createSumObservable(a, b).pipe(delay(500));
}
12 changes: 6 additions & 6 deletions apps/demo/src/app/lazy-routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,17 +62,17 @@ export const lazyRoutes: Route[] = [
),
},
{
path: 'mutation',
path: 'mutation-store',
loadComponent: () =>
import('./counter-mutation/counter-mutation').then(
(m) => m.CounterMutation,
import('./counter-mutation-store/counter-mutation-store').then(
(m) => m.CounterMutationStore,
),
},
{
path: 'rx-mutation',
path: 'mutation-functions',
loadComponent: () =>
import('./counter-rx-mutation/counter-rx-mutation').then(
(m) => m.CounterRxMutation,
import('./counter-mutation-functions/counter-mutation-functions').then(
(m) => m.CounterRxMutationFunctions,
),
},
];