skip to Main Content

I´ve using this method to share data between components because is more agile than observables, services or whatever method… But, I´m using on an angular 15 project and it seems doesnt work.

I have a parent component with an object variable initialized as empty object.

Parent component

exhibitor: object = {};

I have a child component with an input variable which i share reference to exhibitor parent variable

@Input() exhibitorData: object = {};

Then, i share exhihibitor parent with child in template

<app-exhibitor-child [exhibitor-data]="exhibitor"></app-exhibitor-child>

But when I change exhibitorData it doesnt affect to exhibitor parent varible.

this.exhibitorData = { 'property': changed };

I´ve been using this method for years and it doesnt work, angular is creating isolated scopes for each component or what?

EDIT: Lapsus, i need to share object and change properties of that object, not reasignin it.

Parent component

exhibitorData: object = {
    exhibitor: {},
    exhibitorId: ''
}

Use child component like that

<app-exhibitor-child [exhibitor-data]="exhibitorData"></app-exhibitor-child>

If I change exhibitorData.exhibitor in exhibitorChild component then I have same result on exhibitorData.exhibitor parent component.

this.exhibitodData.exhibitor = { 'property': 'changed' }

Sorry for lapsus

2

Answers


  1. When you update the properties inside the property exhibitorData

    this.exhibitorData.property = 1;
    

    Objects are arrays are stored as references, so when the values inside change the memory reference stays the same, so changes are visible in both parent and child, maybe this is what you are referring to.

    But in your case you are doing.

    this.exhibitorData = { 'property': changed };
    

    You are assigning a new object so the memory reference has changed, so the changes are not propagating.


    One way to fix this is to use two way binding.

    On the child, you can create an input and a output, where the important piece of information is that, the output emitter, must have the name as <<propName>>Change, so the change suffix will enable two way binding. Also when you want to update the variable and propagate to the parent, you can use .emit method of the EventEmitter (Imported from @angular/core).

    On the child change the code to below.

    @Input() exhibitorData: object = {};
    @Output() exhibitorDataChange: EventEmitter<any> = new EventEmitter<any>();
    
    changeData() {
        this.exhibitorDataChange.emit({ 'property': changed });
    }
    

    On the parent you can change the binding to two way binding, so both ways the update propogates.

    There is no need to use exhibitor-data, just use the property name as is.

    <app-exhibitor-child [(exhibitorData)]="exhibitor"></app-exhibitor-child>
    
    Login or Signup to reply.
  2. If you want to use one-way binding, you must not assign to this.exhibitorData. You have to modify the object:

    this.exhibitorData.property = changed;
    

    It has nothing to do with Angular. It’s how pass-by-value works in JavaScript.

    Example:

    function f1(obj) {
        obj = { a: 1 };
    }
    
    function f2(obj) {
        obj.a = 1;
    }
    
    const obj1 = { a: 0 };
    const obj2 = { a: 0 };
    
    f1(obj1);
    f2(obj2);
    
    console.log(obj1);
    console.log(obj2);
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search