Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2, Does @Input with a setter behave differently than @Input without a setter?

I am wondering if someone could elaborate on this. Does @Input() with a setter vs using @Input() without a setter behave differently in regards to change detection?

For example:

@Input() something: SomeType; 

-vs-

private _something;

@Input() set something(something: SomeType ) {
  this._something = something;
}

get something(): SomeType {
  return this._something;
}

The obvious difference is that the setter/getter allows @Input() with some extra logic. But does this affect change detection in a different way than if I were to use @Input() without a setter?

like image 785
Kris Hollenbeck Avatar asked Feb 05 '23 05:02

Kris Hollenbeck


2 Answers

For angular not a lot changes. The input won't be set or the setter won't be called more often. There is however a caveat where there is more logic inside the setter which can trigger another change detection. If you have that, angular will throw the known error (only in development mode)

Expression has changed after it was checked.

So, the change detector does not behave differently, but issues may arise depending on what extra logic you put inside the setter

like image 98
Poul Kruijt Avatar answered Feb 07 '23 19:02

Poul Kruijt


From angular's view, the only difference is that you got a chance to hook those @Input()'s get/set functions.

From Javascripts view, first will be "just" a property, second would use Object.defineProperty.

plunker: https://plnkr.co/edit/1koamZCvyG5YAIPNB73r?p=preview

compiled code with setter:

Object.defineProperty(AppComponent.prototype, "test1", {
    get: function () { return this._test1; },
    set: function (val) {
        console.log('test1 was set!');
        this._test1 = val;
    },
    enumerable: true,
    configurable: true
});
__decorate([
    __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_0__angular_core__["Input"])(), 
    __metadata('design:type', Object), 
    __metadata('design:paramtypes', [Object]) /* difference? */
], AppComponent.prototype, "test1", null);

compiled code withOUT setter:

__decorate([
    __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_0__angular_core__["Input"])(), 
    __metadata('design:type', Object)
], AppComponent.prototype, "test2", void 0);

both compiled with angular-cli: ng build.

like image 30
slaesh Avatar answered Feb 07 '23 19:02

slaesh