Search code examples
data-bindingangular7

Angular 7-Sharing variable between components dynamically


I am trying to share a variable between two components. I was able to do so. However, when the variable's value is changed in the parent component, it is not reflected in the child one.

Demo can be found at below:

https://stackblitz.com/github/abdelrahman84/Vacation-Planner-Angular?fbclid=IwAR1gS4ScuGo9mOybQWwrZeGkmKz6MV3QM5d3_bSl0cIxkAXpw7jRu60XOmM

Name of the variable: DiffDate...Original value: 10

Original component of the variable: datepicker-range.ts

Child component to use the variable: app.component.ts

For instance, if you selected only two days as vacation, the difference in days becomes 2. However, in the child, it is still 10.

enter image description here


Solution

  • Short version, components don't share variables with one another without assistance.

    In your case, I recommend you use an EventEmitter recognizing that the app.component is your parent and the datepicker-range is your child. The EventEmitter will allow you to trigger events from the change (i.e. data changes) that the parent can subscribe to.

    This is an awesome video on the subject of sharing data between components: https://www.youtube.com/watch?v=I317BhehZKM

    Here's a solution that worked for me:

    datepicker.range.ts

    Update your imports to include EventEmitter and Output

    import {Component, Input, Output, EventEmitter} from '@angular/core';
    

    Declare output variable as event emitter for the parent to subscribe to

    @Output() dateDifferenceEvent  = new EventEmitter<number>();
    

    Emit an event everytime the difference value is calculated this.dateDifferenceEvent.emit(daysDiff); so the parent can act on it

     private calcDaysDiff(): number {
    
        const fromDate: Date = this.createDateFromNgbDate(this.fromDate);
        const toDate: Date = this.createDateFromNgbDate(this.toDate);  
        const daysDiff = Math.floor(Math.abs(<any>fromDate - <any>toDate) / (1000*60*60*24));
    
        this.dateDifferenceEvent.emit(daysDiff);
    
        return daysDiff;
      }
    

    app.component.html

    Update the child tag to bind to the child output variable dateDifferenceEvent

    <ngbd-datepicker-range (dateDifferenceEvent)="setDifference($event)"></ngbd-datepicker-range>
    

    app.component.ts

    Add the variable to your parent comonent - app.component.ts Keep in mind this in only named DiffDate to match the {{DateDiff}} binding you added in your app.component.html. This can be whatever you want it to be as long and you use that name in your html template binding.

    DiffDate: number;
    

    Add a method to handle the event from the child and update your parent component DateDiff variable with it

      setDifference($event) {
        this.DiffDate = $event; 
      }