Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(signals): add signalMethod #4597

Merged

Conversation

rainerhahnekamp
Copy link
Contributor

signalMethod is a factory function to process side effects on Signals or static values.

It is similar to rxMethod but does not support RxJS.

signalMethod follows Angular's pattern of RxJS-less utilities for Signals, like resource and rxResource.

signalMethod expects a type and processor function:

const doubleLogger = signalMethod<number>(value => console.log(value * 2))

const value = signal(1);
doubleLogger(value); // tracks value and executes initially and on every change

It also supports static values, e.g., doubleLogger(1).

This PR also contains the documentation and tests.

PR Checklist

Please check if your PR fulfills the following requirements:

PR Type

What kind of change does this PR introduce?

[ ] Bugfix
[x] Feature
[ ] Code style update (formatting, local variables)
[ ] Refactoring (no functional changes, no api changes)
[ ] Build related changes
[ ] CI related changes
[ ] Documentation content changes
[ ] Other... Please describe:

Closes #4581

What is the new behavior?

Does this PR introduce a breaking change?

[ ] Yes
[x] No

Copy link

netlify bot commented Nov 17, 2024

Deploy Preview for ngrx-io ready!

Built without sensitive environment variables

Name Link
🔨 Latest commit 5afe80f
🔍 Latest deploy log https://app.netlify.com/sites/ngrx-io/deploys/6750adb8e82d100009bbd869
😎 Deploy Preview https://deploy-preview-4597--ngrx-io.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

Copy link
Member

@timdeschryver timdeschryver left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍

I just left some comments on the docs.
Also, do we want to add a section similar to https://deploy-preview-4597--ngrx-io.netlify.app/guide/signals/rxjs-integration#reactive-methods-without-arguments?

projects/ngrx.io/content/guide/signals/signal-method.md Outdated Show resolved Hide resolved
projects/ngrx.io/content/guide/signals/signal-method.md Outdated Show resolved Hide resolved
projects/ngrx.io/content/guide/signals/signal-method.md Outdated Show resolved Hide resolved
projects/ngrx.io/content/guide/signals/signal-method.md Outdated Show resolved Hide resolved
@rainerhahnekamp
Copy link
Contributor Author

@timdeschryver

Also, do we want to add a section similar to https://deploy-preview-4597--ngrx-io.netlify.app/guide/signals/rxjs-integration#reactive-methods-without-arguments?

We can but then we should also maybe provide a good example. Any ideas?

I was thinking about some reset function which is triggered if a Signal<number> changes?

const userId = signal(1);

signalStore(
  withMethods(store => ({
    reset: signalMethod<void>(() => patchState(store, initialState);
  })
)

@timdeschryver
Copy link
Member

@rainerhahnekamp that's a good question 😅.

Initially I was thinking about a console.log (as with the effects example on angular.dev), but that isn't very useful.

I like the reset example, but then what is the difference between a "normal" method and a signalMethod?

signalStore(
  withMethods(store => ({
    reset: signalMethod<void>(() => patchState(store, initialState)),
    // compared to
    reset2: () => patchState(store, initialState),
  })
)

If we can't think of a good example, then maybe it isn't useful to create a withMethod without any arguments.

@rainerhahnekamp
Copy link
Contributor Author

@timdeschryver

I like the reset example, but then what is the difference between a "normal" method and a signalMethod?

If you have

const userId = signal(1);

store.reset(userId);
store.reset2(userId);

Both will run once, but reset will then also execute whenever userId changes.

@timdeschryver
Copy link
Member

Yes, but that's with an argument.

@rainerhahnekamp
Copy link
Contributor Author

@timdeschryver

Oopsi... then I’m actually running quite short on examples!

Then I'll guess if we don't see a need for it, we don't need to mention it in the docs?

@timdeschryver
Copy link
Member

Sounds good to me @rainerhahnekamp , we can always update it later if needed.

rainerhahnekamp and others added 4 commits December 1, 2024 23:19
`signalMethod` is a factory function to process side effects on Signals or
static values.

It is similar to `rxMethod` but does not support RxJS.

`signalMethod` follows Angular's pattern of RxJS-less utilities for Signals,
like `resource` and `rxResource`.

`signalMethod` expects a type and processor function:

```typescript
const doubleLogger = signalMethod<number>(value => console.log(value * 2))

const value = signal(1);
doubleLogger(value); // tracks value and executes initially and on every change
```

It also supports static values, e.g., `doubleLogger(1)`.
@rainerhahnekamp rainerhahnekamp force-pushed the feat/signals/signal-method branch from b2c253c to 9f05e60 Compare December 1, 2024 22:20
Copy link
Member

@markostanimirovic markostanimirovic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work Rainer! 👏

The implementation part looks good to me. 👍 I left suggestions for documentation:

modules/signals/spec/signal-method.spec.ts Outdated Show resolved Hide resolved
projects/ngrx.io/content/guide/signals/signal-method.md Outdated Show resolved Hide resolved
projects/ngrx.io/content/guide/signals/signal-method.md Outdated Show resolved Hide resolved
projects/ngrx.io/content/guide/signals/signal-method.md Outdated Show resolved Hide resolved
projects/ngrx.io/content/guide/signals/signal-method.md Outdated Show resolved Hide resolved
projects/ngrx.io/content/guide/signals/signal-method.md Outdated Show resolved Hide resolved
projects/ngrx.io/content/guide/signals/signal-method.md Outdated Show resolved Hide resolved
projects/ngrx.io/content/guide/signals/signal-method.md Outdated Show resolved Hide resolved
projects/ngrx.io/content/guide/signals/signal-method.md Outdated Show resolved Hide resolved
projects/ngrx.io/content/guide/signals/signal-method.md Outdated Show resolved Hide resolved
@rainerhahnekamp
Copy link
Contributor Author

@markostanimirovic, as always also thanks for your thorough review. I've committed all your suggestions and moved the 2 destroying tests to their suite.

@markostanimirovic markostanimirovic changed the title feat: add signalMethod (#4581) feat(signals): add signalMethod Dec 2, 2024
@rainerhahnekamp
Copy link
Contributor Author

@markostanimirovic I committed all your requested changes except one. I can't figure out what you meant here: #4597 (comment)

Copy link
Member

@timdeschryver timdeschryver left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👏👏👏

projects/ngrx.io/content/guide/signals/signal-method.md Outdated Show resolved Hide resolved
Copy link
Member

@markostanimirovic markostanimirovic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀

@markostanimirovic markostanimirovic merged commit bdd1d3e into ngrx:main Dec 4, 2024
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

RFC: method - rxMethod without RxJS
3 participants