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: add toObservableSignal() #230

Merged
merged 3 commits into from
Jan 20, 2024
Merged

feat: add toObservableSignal() #230

merged 3 commits into from
Jan 20, 2024

Conversation

e-oz
Copy link
Contributor

@e-oz e-oz commented Jan 17, 2024

toObservableSignal() combines the functionality of Angular Signal and RxJS Observable.

StackBlitz

https://stackblitz.com/edit/stackblitz-starters-owzm3q?file=src%2Fmain.ts

Usage

@Component({
  selector: 'my-app',
  standalone: true,
  imports: [CommonModule],
  template: `
    <h2>Signal A: {{ a() }}</h2>
    <h2>Observable A: {{ a | async }}</h2>
    <h2>Observable B (A*2): {{ b | async }}</h2>
    <h2>Signal C (A*3): {{ c() }}</h2>
  `,
})
export class App {
  a = toObservableSignal(signal<number>(0));
  b = this.a.pipe(
    switchMap((v) => {
      return of(v * 2);
    }),
  );
  c = computed(() => this.a() * 3);
  
  constructor() {
  setInterval(() => this.a.set(1), 10000);
  setInterval(() => this.a.update((v) => v + 1), 1000);
  }
}

`toObservableSignal()` combines the functionality of Angular Signal and RxJS Observable.
Copy link

nx-cloud bot commented Jan 17, 2024

☁️ Nx Cloud Report

CI is running/has finished running commands for commit ddb23c1. As they complete they will appear below. Click to see the status, the terminal output, and the build insights.

📂 See all runs for this CI Pipeline Execution


✅ Successfully ran 3 targets

Sent with 💌 from NxCloud.

@e-oz
Copy link
Contributor Author

e-oz commented Jan 17, 2024

Linter says

  /home/runner/work/ngxtension-platform/ngxtension-platform/libs/ngxtension/package.json
  29:3  error  The "ts-morph" package is not used by "ngxtension" project  @nx/dependency-checks

✖ 3 problems (1 error, 2 warnings)
  1 error and 0 warnings potentially fixable with the `--fix` option.

Please let me know if I can fix this.

@LcsGa
Copy link
Contributor

LcsGa commented Jan 17, 2024

Hi! There are 2 things I'm a little bit "bothered" about here (if I'm not wrong 😅 I'm on my phone so I can't test m'y sayings, sorry) :

  • if you call asReadonly it becomes a Signal and you cannot use pipe, subscribe, etc. anymore
  • the same goes for pipe => it will become an observable (if not right now, it will happen very soon when the rxjs V8 IS released) so you won't be able to use set, update, etc.

=> Is it really a good thing to have something that "unstable"?

@e-oz
Copy link
Contributor Author

e-oz commented Jan 17, 2024

@LcsGa

if you call asReadonly it becomes a Signal and you cannot use pipe, subscribe, etc. anymore

That's ok, it is your explicit choice. You could use a Signal (not a WritableSignal) as an argument, and then everything would work fine. But if you explicitly want to send WritableSignal as an argument, and then cut the result using asReadonly() - that's your choice, no one can stop you.

the same goes for pipe => it will become an observable (if not right now, it will happen very soon when the rxjs V8 IS released) so you won't be able to use set, update, etc

Only the output of pipe(). The variable itself will still be usable as a signal.

@LcsGa
Copy link
Contributor

LcsGa commented Jan 17, 2024

Alright, it makes sense! Thanks for the clarification 🙂

@RobbyRabbitman
Copy link
Contributor

@e-oz I like this idea, what do you think about an option whether the observable is hot or cold? When you specify hot it would skip the initial value.

@e-oz
Copy link
Contributor Author

e-oz commented Jan 18, 2024

@RobbyRabbitman
this function uses toObservable() from rxjs-interop, and toObservable() uses ReplaySubject and effect(), so observables are hot, and the first value will be emitted when effect() reads the values for the first time (right now is the next microtask, I believe).

We could, indeed, change it, and control if the first value should be written to an observable synchronously (instantly) or if it should be skipped. Maybe later :) For now, I prefer to rely on toObservable(), as it is a more battle-tested solution.

@RobbyRabbitman
Copy link
Contributor

By hot I meant to skip the value, which is read the first time by the effect. Maybe that's the wrong term.

@nartc
Copy link
Collaborator

nartc commented Jan 20, 2024

@e-oz Fixed the lint issue. I'll merge as soon as CI's green. Thank you

@nartc nartc merged commit 2c7e42c into ngxtension:main Jan 20, 2024
6 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.

4 participants