Updating a neighboring input variable in Angular 2 whenever an input variable is modified

When modifying input parameters, I aim to execute certain operations. For instance, suppose I have a DatePicker component with a type input variable. I intend to trigger some actions involving another date variable when the type is altered. How can this be accomplished?

export class DatePicker {

    @Input()
    date: Date;

    @Output()
    dateChange = new EventEmitter();

    @Input()
    set type(type: string) {
        if (type === "today") {
            this.date = new Date();
            this.dateChange(this.date); // this change triggers an error in the change detector
        }
    }

}

Error: Expression has changed after it was checked.

Answer №1

Upgrade

Encountering an error in Angular2 can occur when the change detection process itself triggers model alterations, highlighting a potential bug or a flaw in the design that impacts the efficiency of Angular2 applications.

To resolve such issues, one can simply activate prodMode.

To address model changes in lifecycle methods, you can explicitly call

ChangeDetectorRef.detectChanges()
to indicate that the model alteration is intentional.

export class DatePicker {

    constructor(private cdRef:ChangeDetectorRef) {}

    @Input()
    date: Date;

    @Output()
    dateChange = new EventEmitter();

    @Input()
    set type(type: string) {
        if (type === "today") {
            this.date = new Date();
            this.dateChange(this.date); 
            this.cdRef.detectChanges();
        }
    }
}

Initial

You have the option to use setTimeout(). setTimeout() is a brute force method that triggers a change detection cycle for the entire application.

@Input()
set type(type: string) {
    if (type === "today") {
        this.date = new Date();
        setTimeout(() => this.dateChange(this.date)); 
    }
}

This becomes crucial when type is modified by change detection, as Angular2 does not respond well to change detection-induced alterations.

Alternatively, you can utilize ngOnChanges(), but this method is also invoked by change detection and requires the setTimeout() workaround.

export class DatePicker implements OnChanges {

    @Input()
    date: Date;

    @Output()
    dateChange = new EventEmitter();

    @Input()
    set type:string;

    ngOnChanges(changes:SimpleChanges) {
      if(changes['type']) {
        if (type === "today") {
            this.date = new Date();
            setTimeout(() => this.dateChange(this.date));
        }
      }
    }
}

The distinction between these two approaches lies in the fact that the first one executes the code for every alteration, while the latter only operates for changes induced by bindings.

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

What is the cause of the error message "property 'map' is undefined"?

I am currently working on a service that looks like this: public getUsers() { return this.httpClient.get(environment.BASE_URL + `api/all`); } In my component, I have implemented the ngx-bootstrap table to display the user data. import { Component, OnI ...

Is it possible for ngIf to only hide the div without impacting the overall layout?

I utilize a left side menu and main content. <div class="row"> <div ngIf="loginUser" class="sidebar col-md-3> ....... </div! <div class="main col-md-9> ....... </div> </div> It is hidden when ...

How to display a PDF in Angular 6 using a byte array retrieved from a WebAPI

Having trouble opening a PDF from byte array sent by WebAPI. This is my Service: fetchPdfDocument(): Observable<any> { return this.httpClient .get(this.configuration.serverUrl + this.configuration.getPdfDoc, { re ...

What is the best way to replicate certain key-value pairs in an array of objects?

I am working with an array of objects. resources=[{name:'x', title:'xx',..},{name:'y',title:'yy',..}..] To populate my HTML tooltip, I am pushing all the titles from the resources array to a new array. dialogOkCli ...

How can one properly extend the Object class in JavaScript?

I have a scenario where I want to enhance a record (plain Javascript object) of arrays with additional properties/methods, ideally by instantiating a new class: class Dataframe extends Object { _nrow: number; _ncol: number; _identity: number[]; co ...

Top method for dynamically loading a specific component by using its selector as a variable

I'm currently in the process of developing a straightforward game using Angular. The game is structured to consist of multiple rounds, each with unique characteristics that are distinguished by the variable roundType. For instance, round types can in ...

What steps do I need to take for webpack to locate angular modules?

I'm currently in the process of setting up a basic application using Angular 1 alongside Typescript 2 and Webpack. Everything runs smoothly until I attempt to incorporate an external module, such as angular-ui-router. An error consistently arises ind ...

Having trouble with SVG Circles - Attempting to create a Speedometer design

Trying to implement a speedometer in one of the components of my Vue project, but encountering an issue. When I input 0 into my progress calculation for determining the stroke fill, it overlaps with the background circle instead of staying within its bound ...

Get React-table TS up and running on your local machine using VS Code

Objective: I am trying to get React-table working with TypeScript on my local computer. Challenge: The code is based on this page https://codesandbox.io/s/gkzg3?file=/src/makeData.ts However, when I attempt to apply the code on my local computer, I ...

Angular 6 Error: Failed to parse template. Unable to establish a connection with 'routerLink' as it is not recognized as a valid property of 'a'

During app testing with npm test An error is encountered : Failed: Template parse errors: Can't bind to 'routerLink' since it isn't a known property of 'a'. (" <nav> <ul> <li><a class=" ...

Are you a skilled UI Designer looking to work with JHipster?

Just starting out with JHipster and I've generated my first Angular 2 project using JHipster 4.5.1. It's been an amazing journey so far! Now, I'm looking to customize the default JHipster generated Angular 2 pages and create my own custom p ...

Angular - Exploring the process of creating a secondary standalone build for a specific section of an application

I have created an Angular 4 (or 5) application with a specific structure as shown in the image below: https://i.sstatic.net/zK1BM.png Now, I need to develop a separate standalone angular application where only a selected group of Angular components from ...

Using React along with TypeScript to specify the type of useState as an object containing key/value pairs of strings

I'm currently working in React with typescript and attempting to set the type of useState as an object containing string key/value pairs. Despite searching on SO, I haven't found a solution yet. I've experimented with <{ [key: string]: s ...

Angular: ngx-responsive has a tendency to hide elements even if they meet the specified conditions

Recently, I started using a library called this to implement various designs for desktop and mobile versions of an Angular app (v4.2.4). Although the documentation recommends ngx-responsive, I opted for ng2-responsive but encountered issues. Even after set ...

Error message encountered following the removal of an undesirable type from an array in Typescript

When working with TypeScript, I am facing an issue. I have an array defined as Array<string|undefined, and my goal is to filter out the undefined values from this array and assign the resulting array to a variable of type Array<string>. However, I ...

Incorporate a Custom Icon into NbSelect

I am currently utilizing Nebular in a project, where multiple dropdowns are being used as shown below: <nb-select fullWidth placeholder="Office" formControlName="office"> <nb-option value="Office_A"&bt;Office A</n ...

What is the best approach to converting an array of strings into a TypeScript type map with keys corresponding to specific types?

The code provided below is currently working without any type errors: type Events = { SOME_EVENT: number; OTHER_EVENT: string } interface EventEmitter<EventTypes> { on<K extends keyof EventTypes>(s: K, listener: (v: EventTypes[K]) => voi ...

Error encountered: The build failed due to the presence of two distinct types sharing the same name, however, they

Encountering an error during the build of my JHipster Angular project [ERROR] Error at /Users/Dan/work/gba/node_modules/ng-jhipster/src/interceptor/interceptable-http.d.ts:4:22: Class 'InterceptableHttp' incorrectly extends base class 'Http ...

Having trouble finding the "make:migration" command in Adonis 5 - any suggestions?

After reviewing the introductory documentation for Adonis Js5, I attempted to create a new API server. However, when compiling the code using "node ace serve --watch" or "node ace build --watch", I kept receiving an error stating "make:migration command no ...

Can we improve the coding of this as it seems inefficient and uses up too much room?

Do you think there is a more efficient way to write this code? It seems quite impractical and takes up a lot of space. Essentially, it's about the random chance of obtaining a rarity, like acquiring an Uncommon sword. if (Math.random() * 100 < 100 ...