1

I wanted to ask this in the Angular's project Github, but apparently questions/clarifications belongs to StackOverflow, so here we are :)

Lib authors can implement two-way binding using the new model() function. By using this function, Angular automatically creates a corresponding output for that model, ultimately making possible to use the [property] and (propertyChange) pattern. However, the component immediately emits the default/initial value through the output event as soon as it's initialized.

For example, with this third-party component:

@Component(...)
export class ThirdPartyChildComponent {
  value = model.required<string>();
}

And using it like this:

@Component({
  template: `<third-party-child [value]="defaultValue()" (valueChange)="logValueChange($event)">`
})
export class ParentComponent {
  public defaultValue = input('initial value');
  public logValueChange(value: string) {
    console.log(value);
  }
}

The logValueChange method is called immediately with 'initial value' during initialization.

Expected Behavior

As a consumer, I would expect the output event (valueChange) to only emit when the value actually changes after initialization, not immediately upon receiving the initial input value.

In this stackblitz this initial emission doesn't occur in the ngModel, Angular Forms or even Html Inputs.

Technically speaking, I do understand why by using the model() this might happen, but I'm trying to determine if:

  • This is a design issue with the third-party component
  • Perhaps related to a version specific issue?
  • Should library authors provide separate mechanisms for initial values vs. change events?
  • It's on my end as a consumer to differentiate between the first emission and future emissions
2
  • 1
    not an angular issue stackblitz event is not fired Commented Apr 10 at 8:21
  • Oh, interesting... so might be an issue on the third-party lib implementation :0 Commented Apr 10 at 8:24

1 Answer 1

1

As seen in the below stackblitz, there is no trigger of change event on initial load.

The possible reasons could be:

  1. The model could be modified on initial load, which triggers the change event (Third party code).
  2. Could be a version specific bug where the change event fires.

import { Component, model } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';

@Component({
  selector: 'app-child',
  imports: [FormsModule],
  template: `
    <input type="text" [(ngModel)]="name">
  `,
})
export class Child {
  name = model();
}

@Component({
  selector: 'app-root',
  imports: [Child],
  template: `
    <app-child [name]="name" (nameChange)="nameChange($event)"/>
  `,
})
export class App {
  name = 'Angular';

  nameChange(event: any) {
    console.log('name change', event);
  }
}

bootstrapApplication(App);

Stackblitz Demo

Sign up to request clarification or add additional context in comments.

2 Comments

You are right. I wrongly assumed there was an issue with the model() itself (thus Angular related) but I have tried several Angular versions using your demo and I'm not able to reproduce it. I guess the ThirdPartyComponent is doing something with the model() making it emit the default value initially.
@WSD yes, try checking the source code if possible or raise a github issue on the third party code, but you can easily avoid this by doing isFirst = true; nameChange(event: any) { if(isFirst && name !== event) { this.isFirst = false; console.log('name change', event); } }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.