Skip to content

Commit

Permalink
fix(ngx-control-value-accessor): accessing properties is outside of t…
Browse files Browse the repository at this point in the history
…he reactive context
  • Loading branch information
Robby Rabbitman committed Feb 4, 2025
1 parent b569bab commit b399dd6
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { CommonModule } from '@angular/common';
import { Component, Provider, inject } from '@angular/core';
import { Component, Provider, effect, inject } from '@angular/core';
import { TestBed, fakeAsync, flush } from '@angular/core/testing';
import {
FormControl,
Expand Down Expand Up @@ -210,6 +210,80 @@ describe('NgxControlValueAccessor', () => {
);
});

describe('accessing properties should be outside a reactive context', () => {
it('value', () => {
const { cva, fixture } = render(`<custom-input />`);

let effectCallCount = 0;

TestBed.runInInjectionContext(() => {
effect(() => {
effectCallCount++;

// accessing the value property should not register the internal signal
cva.value;
});
});

// initial effect execution
fixture.detectChanges();
expect(effectCallCount).toEqual(1);

// setting the value should not trigger the effect
cva.value = '123';
fixture.detectChanges();
expect(effectCallCount).toEqual(1);
});

it('disabled', () => {
const { cva, fixture } = render(`<custom-input />`);

let effectCallCount = 0;

TestBed.runInInjectionContext(() => {
effect(() => {
effectCallCount++;

// accessing the disabled property should not register the internal signal
cva.disabled;
});
});

// initial effect execution
fixture.detectChanges();
expect(effectCallCount).toEqual(1);

// setting the value should not trigger the effect
cva.disabled = !cva.disabled;
fixture.detectChanges();
expect(effectCallCount).toEqual(1);
});

it('compareTo', () => {
const { cva, fixture } = render(`<custom-input />`);

let effectCallCount = 0;

TestBed.runInInjectionContext(() => {
effect(() => {
effectCallCount++;

// accessing the compareTo property should not register the internal signal
cva.compareTo;
});
});

// initial effect execution
fixture.detectChanges();
expect(effectCallCount).toEqual(1);

// setting the value should not trigger the effect
cva.compareTo = () => true;
fixture.detectChanges();
expect(effectCallCount).toEqual(1);
});
});

describe('with a NgControl', () => {
it('should be the control value accessor', () => {
const { ngControl, cva } = render(`<custom-input ngModel />`);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
inject,
runInInjectionContext,
signal,
untracked,
type OnInit,
} from '@angular/core';
import { toObservable } from '@angular/core/rxjs-interop';
Expand Down Expand Up @@ -271,7 +272,7 @@ export class NgxControlValueAccessor<T = any>
}

public get value() {
return this.value$();
return untracked(this.value$);
}

/** Whether this is disabled. If a control is present, it reflects it's disabled state. */
Expand All @@ -281,7 +282,7 @@ export class NgxControlValueAccessor<T = any>
}

public get disabled() {
return this.disabled$();
return untracked(this.disabled$);
}

/**
Expand All @@ -295,7 +296,7 @@ export class NgxControlValueAccessor<T = any>
}

public get compareTo() {
return this.compareTo$();
return untracked(this.compareTo$);
}

/**
Expand Down

0 comments on commit b399dd6

Please # to comment.