Coder Social home page Coder Social logo

Comments (10)

Harpush avatar Harpush commented on April 29, 2024 1

One use case for this is wrapping third party (non angular) libraries. For example if such library allow binding to mouse move event and I want to allow my component user to add a (for example) chart mouse move output I will need to always listen to the third party event. If I could know if output was declared I could optimize and won't listen to that event unnecessarily.
An input here doesn't make sense as the one using my component shouldn't configure internal optimization based on how the wrapped third party works.

from angular.

yjaaidi avatar yjaaidi commented on April 29, 2024 1

Very interesting issue. Thanks @GuillaumeNury for raising this.

TL;DR: I wouldn't recommend changing OutputRef API for this as there are decent solutions but if we really go that road than we have to think about what we really want to expose (a boolean? the count? the listeners?)

I totally agree with @devversion on this except on this point:

Subjectively, it would seem confusing to me if the behavior of a component changes based on an output that I subscribe to.

where I think that this is not subjective, but really objective 😊

First, I think that it makes outputs align with DOM event listeners which do not affect DOM behavior.
Additionally, this assumption is also an enabler for testing tools or dev tools. For example, some dev/testing tool could track all component outputs to debug them manually or to compare them to a previous run etc...

In the case of performance optimization, I think that outputFromObservable is a the best alternative to subscribe lazily to expensive sources (like @Harpush's example of a 3rd party mouse tracking lib).

That is why I'd generally recommend being explicit and use inputs in Guillaume's case.

This way we can reduce the OutputRef's API surface and keep it simple.

Meanwhile, if you really want to go with magic 😊, or if it is really needed to debug or optimize something, the solution could be a SnitchyEventEmitter πŸ˜‰: https://stackblitz.com/edit/angular-output-snitching?file=src%2Fmain.ts

If some additional API should be added to OutputRef, then we have to think of whether it's a boolean value or the count of listeners or maybe the listeners?
Indeed, a component might want to throw an error if an output is subscribed to more than once (this can happen through imperative APIs).
For the listeners themselves, I don't have a use case, but for some testing scenarios (that I wouldn't recommend), one might want to trigger a listener from the test.

from angular.

GuillaumeNury avatar GuillaumeNury commented on April 29, 2024 1

As observed is not likely to change (from the template you cannot subscribe from an output and then cancel the cancellation), I can use a simple Subject and outputFromObservable to achieve what I need:

@Component({
  standalone: true,
  selector: 'app-child',
  template: `
  <h2>{{ actionEmitter.observed ? 'πŸ‘€' : 'πŸ™ˆ' }}</h2>
  <button
    [disabled]="!actionEmitter.observed"
    (click)="actionEmitter.next()">CLICK</button>
  `,
})
export class Child {
  actionEmitter = new Subject<void>();
  action = outputFromObservable(this.actionEmitter);
}

(observed is not a signal anymore but a regular boolean. Subject already track its observers)

Stackblitz : https://stackblitz.com/edit/angular-output-snitching-wd3hf4?file=src%2Fmain.ts

Thanks @yjaaidi for the pointer (and the stackblits)!

As the workaround looks simple, maybe we can close this issue?

from angular.

yjaaidi avatar yjaaidi commented on April 29, 2024 1

Cool! Happy to hear that this works for you.

is not likely to change (from the template you cannot subscribe from an output and then cancel the cancellation
Indeed.

Not likely but still possible in case there is an imperative subscription (e.g. testing or viewChild() usage or dynamic creation). So in that case, the view might not be updated if using ChangeDetectionStrategy.OnPush (or this would cause in error in the future signal-based components).

Just an observation here for anyone reading this in the future. Not all observables have the observed property.
In case the source is not a Subject but an Observable (e.g. FormGroup#valueChanges), then you might need something similar to countObservers operator from the stackblitz above.

from angular.

alxhub avatar alxhub commented on April 29, 2024

If we did expose such a property, it would probably be a Signal<boolean>.

from angular.

GuillaumeNury avatar GuillaumeNury commented on April 29, 2024

It would be even better!

from angular.

kbrilla avatar kbrilla commented on April 29, 2024

What about output.required? which would error if no listeners would be registred? - of course I can create separate issue if needed, but it seems like aother solution to the same problem.

from angular.

GuillaumeNury avatar GuillaumeNury commented on April 29, 2024

The output would need to be required only when an input has a specific value (if I understand what is on your mind)

from angular.

kbrilla avatar kbrilla commented on April 29, 2024

Yeah, Now I see difrence, in your proposition it’s more about conditional required based on value of some input / directive. So yeah I will open new issue as both solutions solve difrent issues. Sory for clogging this issue

from angular.

devversion avatar devversion commented on April 29, 2024

Yeah, this is one of the follow-up's we did consider and would implement using a Signal<boolean> as Alex pointed out.

For the use-cases, we did see a similar pattern, especially with expensive subscriptions only being triggered upon "interest from the parent".

The initial thinking still was that an input likely makes more sense here. Subjectively, it would seem confusing to me if the behavior of a component changes based on an output that I subscribe to. That is because "inputs" can "configure" the directive, but outputs simply emit values to the parent conceptually. It's more explicit and keeps the mental model simpler IMO.

In either case, adding such a signal to OutputRef is trivial.

from angular.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.