sonEtLumiere
sonEtLumiere

Reputation: 4572

Angular call parent component function from child component, update variable in real time from sessionStorage

The code starts with an initial value in product variable, which is setted into sessionStorage. When i trigger the side-panel (child component), this receive the product.name from params in url, then this component searchs in sessionStorage and updates the product.amount value (and set it to sessionStorage).

The parent component function that i'm trying to invoke from the child component is getProductStatus(); When i update the product.amount value in the side-panel i need to update also the product object in parent component at the same time. This is what i've been trying, Thanks in advance.

Code: https://stackblitz.com/edit/angular-ivy-npo4z7?file=src%2Fapp%2Fapp.component.html

export class AppComponent {

  product: any;
  productReturned: any;

  constructor() {
    this.product = {
      name: 'foo',
      amount: 1
    };
  }

  ngOnInit() {
    this.getProductStatus();
  }

  getProductStatus(): void {
    this.productReturned = this.getStorage();
    if (this.productReturned) {
      this.product = JSON.parse(this.productReturned);
    } else {
      this.setStorage();
    }
  }

  setStorage(): void {
    sessionStorage.setItem(this.product.name, JSON.stringify(this.product));
  }

  getStorage() {
    return sessionStorage.getItem(this.product.name);
  }

  reset() {
    sessionStorage.clear();
    window.location.reload();
  }
}

Upvotes: 2

Views: 2508

Answers (1)

H3AR7B3A7
H3AR7B3A7

Reputation: 5261

You have two options for data sharing in this case. If you only need the data in your parent component:

In child.component.ts:

@Output() someEvent = new EventEmitter

someFunction(): void {
  this.someEvent.emit('Some data...')
}

In parent template:

<app-child (someEvent)="handleSomeEvent($event)"></app-child>

In parent.component.ts:

handleSomeEvent(event: any): void {
  // Do something (with the event data) or call any functions in the component
}

If you might need the data in another component aswell, you could make a service bound to the root of the application with a Subject to subscibe to in any unrelated component wherever in your application.

Service:

@Injectable()
export class DataService {

  private _data = new BehaviorSubject<SnapshotSelection>(new Data());
  private dataStore: { data: any }

  get data() {
    return this.dataStore.asObservable();
  }

  updatedDataSelection(data: Data){
    this.dataStore.data.push(data);
  }
  
}

Just pass the service in both constructors of receiving and outgoing component.

In ngOnInit() on receiving side:

subscription!: Subscription
...
dataService.data.subscribe(data => {
  // Do something when data changes
})
...
ngOnDestroy() {
  this.subscription.unsubscribe()
}

Then just use updatedDataSelection() where the changes originate.

I documented on all types of data sharing between components here:

https://github.com/H3AR7B3A7/EarlyAngularProjects/tree/master/dataSharing

For an example on the data service:

https://github.com/H3AR7B3A7/EarlyAngularProjects/tree/master/dataService

Upvotes: 1

Related Questions