@@ -226,6 +226,7 @@ export class TippyDirective implements OnChanges, AfterViewInit, OnInit {
226
226
private destroyRef = inject ( DestroyRef ) ;
227
227
private isServer = isPlatformServer ( inject ( PLATFORM_ID ) ) ;
228
228
private tippyFactory = inject ( TippyFactory ) ;
229
+ private destroyed = false ;
229
230
230
231
constructor (
231
232
@Inject ( TIPPY_CONFIG ) protected globalConfig : TippyConfig ,
@@ -240,6 +241,7 @@ export class TippyDirective implements OnChanges, AfterViewInit, OnInit {
240
241
this . setupListeners ( ) ;
241
242
242
243
this . destroyRef . onDestroy ( ( ) => {
244
+ this . destroyed = true ;
243
245
this . instance ?. destroy ( ) ;
244
246
this . destroyView ( ) ;
245
247
this . visibilityObserverCleanup ?.( ) ;
@@ -569,7 +571,12 @@ export class TippyDirective implements OnChanges, AfterViewInit, OnInit {
569
571
private onHidden ( instance : TippyInstance = this . instance ) {
570
572
this . destroyView ( ) ;
571
573
const isVisible = false ;
572
- this . isVisible . set ( isVisible ) ;
574
+ // `model()` uses `OutputEmitterRef` internally to emit events when the
575
+ // signal changes. If the directive is destroyed, it will throw an error:
576
+ // "Unexpected emit for destroyed `OutputRef`".
577
+ if ( ! this . destroyed ) {
578
+ this . isVisible . set ( isVisible ) ;
579
+ }
573
580
this . visibleInternal . next ( isVisible ) ;
574
581
if ( this . visible . observed ) {
575
582
this . ngZone . run ( ( ) => this . visible . next ( isVisible ) ) ;
0 commit comments