Triggering the detection of changes even when the value linked to remains the same

I'm facing an issue with a component that is supposed to react to changes in input controls by reformatting the input and removing certain characters. If the removed character corresponds to the previous value, the component fails to detect any change and does not update. This results in the removed character staying in the input box along with the new value.

Is there a way to ensure that an input box bound via [(ngModel)] to a backing field updates itself to reflect the value returned by the get prop() method?

export class RowConfig {
  constructor(public amount = 0, ...) { }

  get rendition() {
    let output = "";
    if (this.amount !== null && this.amount !== undefined)
      output = ("" + this.amount)
        .replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1 ");
    return output;
  }
  set rendition(input: string) {
    const negative = input.match(/^[-]/);
    const digits = input.replace(/\D/g, "");
    let output = null;
    if (digits)
      output = +digits * (negative ? -1 : 1);
    this.amount = output;
  }
}

The binding is implemented as follows.

<input #amount type="text"
       (keyup)="onKeyUp($event)"
       [(ngModel)]="config.rendition">

I have attempted to trigger change detection in the onKeyUp method using markForCheck() and detectChanges() as suggested in the documentation, but it did not yield any results.

Is there a way to force the input box to clear its current content and update it with the value from the bound property?

(You can try out a demo of this issue on Blitzy.)

Answer №1

To ensure the view updates even if the final value is the same as the existing one, a method involves calling

ChangeDetectorRef.detectChanges()
after setting the initial value, then updating it with the correct value.

For instance, if you have a text field that permits only digits, and the processing occurs in the component code, you can define the setter like this:

private _numericString: string;

get numericString() {
  return this._numericString;
}
set numericString(value) {
  this._numericString = value;     // <------------------------ Set the raw value
  this.changeDetectorRef.detectChanges();   // <--------------- Trigger change detection
  this._numericString = value.replace(/[^\d]/gi, ""); // <----- Set the corrected value
}

Check out the demo on StackBlitz.


In the actual code, config.Rendition is a getter/setter property in a separate class, with formatting in both get and set, complicating the change detection process. To work around this, you can create a configRendition getter/setter property in the component and bind it to ngModel:

<input #amount type="text" placeholder="xxx" [(ngModel)]="configRendition">

The implementation of configRendition involves triggering

ChangeDetectorRef.detectChanges()
first with the raw value, before updating config.Rendition:

private rawRendition: string;

get configRendition() {
  if (this.rawRendition) {
    return this.rawRendition;
  } else {
    return this.config ? this.config.rendition : null;
  }
}
set configRendition(value) {
  this.rawRendition = value;
  this.detector.detectChanges();
  if (this.config) {
    this.config.rendition = value;
  }
  this.rawRendition = null;
}

View the demonstration on StackBlitz here.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

"Jest test.each is throwing errors due to improper data types

Currently, I am utilizing Jest#test.each to execute some unit tests. Below is the code snippet: const invalidTestCases = [ [null, TypeError], [undefined, TypeError], [false, TypeError], [true, TypeError], ]; describe('normalizeNames', ...

Using TypeScript to define a static enum within a React functional component

Creating a React.FunctionalComponent with static props: import MyAwesomeComponent from './MyAwesomeComponent'; ... <MyAwesomeComponent mode={MyAwesomeComponent.modes.superAwesome} /> Static props defined as key-value pairs: MyAwe ...

Restricting a generic parameter to a combination type in Typescript

Is there a method in Typescript to restrict a generic parameter to only accept a union type? To clarify my question, I wish that T extends UnionType would serve this purpose: function doSomethingWithUnion<T extends UnionType>(val: T) {} doSomethingW ...

Automatically generated error notifications for Express-Validator

I am looking to implement an Express API and incorporate request input validation using express-validator. Here is my current validation middleware: protected validate = async (request: Request, response: Response, next: NextFunction): Promise<void> ...

Jest: Test fails due to import statement in node_module dependency

Short Version I'm experiencing a crash in my Jest test due to a SyntaxError related to an import statement outside a module. The issue arises from a node_module that uses the import statement. How can I resolve this error? Situation Overview In deve ...

Is there a way to identify modifications in an Object and an Array when utilized as Input attributes in a sub-component?

After exploring the following two questions, I found that there weren't any helpful answers: Detect change in object of input array Detect changes in component input when it is a object In my current scenario, I am faced with the need to pass variou ...

Removing a dynamic component in Angular

Utilizing Angular dynamic components, I have successfully implemented a system to display toaster notifications through the creation of dynamic components. To achieve this, I have utilized the following: - ComponentFactoryResolve - EmbeddedViewRef - Ap ...

Converting JSON HTTP response to an Array in AngularJS 2: A Comprehensive Guide

As I work on a Http get request in Angular 2, the response returned is in JSON format. However, I am facing an issue when trying to use it in a ngFor loop because it is not formatted as an Array. Is there a way to convert JSON data to an Array in Angular ...

Inform the PHP backend that the browser has been closed by the frontend Angular application

Currently, I am working on an Angular project that is interacting with a backend project created using PHP and ZF3. I am trying to figure out the most efficient method of informing the backend project when the user closes the browser window. Initially, I ...

Flex: 1 does not completely fill the Angular layout div in vertical dimensions

I am currently developing a sidebar using Angular and Flex. The app-sidebar is nested within the Angular component layout shown below: <div fxlayout="row" fxFill> <app-sidebar fxLayout="column" fxFlex="10%"></app-sidebar> <div ...

What is the method for utilizing an alias at the top within a subquery?

Is it possible to use an alias from the top query in a subquery? I am currently encountering an error with 'artc'. let myQuery = this.articles.createQueryBuilder('artc') .select(['artc.title']) .addSelect(qb => ...

"Exploring the advancements in inner calls and the deprecation of forkJoin

Here is the code snippet I am currently working with: ngOnInit(): void { this.issueService.getIssues().pipe( switchMap(issues => { this.issuesList = issues; const observables = this.issuesList.map(issue => this.issueService.getChild ...

Integrate incoming websocket information with state management in React

I am facing a challenge in creating a timeseries plot with data obtained from a websocket connection. The issue arises when new values overwrite the previously stored value in the state variable. const [chartData, setChartData] = React.useState(null) Cu ...

Leverage ngFor to loop through a "highly intricate" data structure

In my project, I have stored data in a JSON file structured as follows: { "name": { "source1": ____, "source2": ____, "source3": ____ }, "xcoord": { "source1": ____, "source2": ____, "source3": _ ...

Managing empty functions as properties of an object in a React, Redux, and Typescript environment

I'm feeling a little uncertain about how to properly test my file when using an object with a function that returns void. Below are the details. type Pros={ studentid: StudentId pageId?: PageID closeForm: () => void } When it comes to creating ...

Angular script error when running 'npm run' on select computers causing Unix command issues for some users but not all

Recently, I've encountered a puzzling issue at my workplace that has been difficult to diagnose. We utilize scripts in npm within the Angular framework to launch a local server instance. Strangely enough, some of my colleagues' computers are thro ...

Tips for accessing a Literal type in TypeScript instead of a Union type

I recently developed a function to generate dynamic elements. However, I encountered an issue where instead of returning the precise type of the element, it was producing a union of various <HTMLElementTagNameMap> types. function createCustomElement( ...

Why aren't the child elements in my React / Framer Motion animation staggered as expected?

In my finance application, I am creating a balance overview feature. To display the content, I pass props into a single <BalanceEntry> component and then map all entries onto the page. With Framer Motion, my goal is to animate each rendered <Bala ...

What is the best way to restrict the suggested values in a property depending on the value of another property?

I'm working on creating a third interface that depends on the value of properties from two other interfaces, while also introducing a unique third property. I've chosen not to extend the third property from the first two interfaces as it may not ...

Custom options titled MUI Palette - The property 'primary' is not found in the 'TypeBackground' type

I am currently working on expanding the MUI palette to include my own custom properties. Here is the code I have been using: declare module '@mui/material/styles' { interface Palette { border: Palette['primary'] background: Pa ...