I'm testing signalState and I wonder how to pass multiple arguments to an rxMethod function.
In my store.ts:
constructor() {
this.fetchData(stringArray1$, observable2$)
}
readonly fetchData = rxMethod<--?-->(
pipe(
doSomething(),
)
)
What do I need to pass in the argument of the rxMethod function?
rxMethod is an entry point to an observable - it cannot have more than one argument as any observable can pipe just one value at time.
Instead of multiple parameters use an object with its keys.
https://ngrx.io/api/signals/rxjs-interop/rxMethod
Check this out:
import { Component, Injector, effect, inject, signal } from '@angular/core';
import { DatePipe } from '@angular/common';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { rxMethod } from '@ngrx/signals/rxjs-interop';
import { signalStore, withMethods, withState, patchState } from '@ngrx/signals';
import { bootstrapApplication } from '@angular/platform-browser';
import 'zone.js';
import { pipe, tap, timer } from 'rxjs';
interface RxInput {
input: string;
date: Date;
}
interface RxValue {
value: string;
date: Date;
}
interface State {
input: RxInput;
value: RxValue;
}
const Store = signalStore(
{ providedIn: 'root' },
withState<State>({
input: { input: '', date: new Date() },
value: { value: '', date: new Date() },
}),
withMethods((store) => ({
setInput: (input: RxInput) => {
patchState(store, (state: State) => {
return {
...state,
input: {
input: input.input,
date: input.date,
},
};
});
},
inputPipe: rxMethod<RxInput>(
pipe(
tap((input) =>
patchState(store, (state: State) => {
return {
...state,
value: {
value: `rxValue-${input.input}`,
date: input.date,
},
};
})
)
)
),
}))
);
@Component({
selector: 'app-root',
standalone: true,
template: `
<h1>Hello from {{ name }}!</h1>
<h2><b>INPUT</b></h2>
<p><b>Date:</b> {{store.input.date() | date:'YYYY-MM-dd HH:mm:ss'}}</p>
<p><b>Value:</b> {{store.input.input()}}</p>
<h2><b>VALUE</b></h2>
<p><b>Date:</b> {{store.value.date() | date:'YYYY-MM-dd HH:mm:ss'}}</p>
<p><b>Value:</b> {{store.value.value()}}</p>
`,
imports: [DatePipe],
})
export class App {
store = inject(Store);
name = 'Angular';
constructor() {
this.store.inputPipe(this.store.input);
timer(1000, 2000)
.pipe(
tap((value) =>
this.store.setInput({ input: value.toString(), date: new Date() })
),
takeUntilDestroyed()
)
.subscribe();
}
}
bootstrapApplication(App);
demo@stackblitz
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With