Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass multiple arguments to an rxMethod fuction?

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?

like image 732
ehtomit Avatar asked Nov 02 '25 17:11

ehtomit


1 Answers

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

like image 167
Pawel Twardziak Avatar answered Nov 04 '25 10:11

Pawel Twardziak