Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access parent component properties from a child route component in Angular?

I'm new to Angular and I'm stuck there. I know how to share data between parent and child components simply by injecting [parentData]="var" into the child selector <>.

But when using routing; I only have a router-outlet and can't bind [parentData] to it as it throws an error.

What is the best and easiest way to access parent properties from a child's route?

The project is on stackblitz here.

I need to display products (from the parent component) inside the child component.

version:(Angular 5)

like image 465
shireef khatab Avatar asked Feb 27 '18 10:02

shireef khatab


2 Answers

Yes this is pretty simple, when you want to pass to component that are in router-outlet you need to use services, actually that component do not exist in the template before you go to the right path, so usual bindings don't work here.

So the best way to work this around is to create some simple service

In the service

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';

@Injectable()
export class DataTransferService {

  private products= new BehaviorSubject<any>([]);
  cast= this.products.asObservable();

  sendAnything(data) {
    this.products.next(data);
  }

}

then inject your service into both constructors of your parent and child component

In parent component

 constructor(private dataTransfer: DataTransferService){}

then create a method

 shareData(data){
    this.dataTransfer.sendAnything(data) // to send something
}

and call it from the parent.component.html with

(click)="shareData(data)" // data is the parent data that you want to share

In child component

inside the ngOnInit method add:

 ngOnInit() {
   this.dataTransfer.products.subscribe(res=> this.var = res) // var is the property that you want to assign the data to it.
 }

to get the data and work with it.
more info and examples You can find in doc

like image 148
Kraken Avatar answered Sep 28 '22 05:09

Kraken


On the one hand, you can not pass an input to the router-outlet tag since the component added by the router will be a sibling to the tag and won't replace it.

On the other, When your Angular application becomes more and more complex, passing the same input from the parent components to the child ones will no longer be the right way to do things..

In your case, the best way to deal with the products variable is to declare it as a behavior subject in the products service:

   prodcuts:Subject<IProducts[]> = new BehaviorSubject<IProducts[]>([]);

and in the parent component, you send the received data:

ngOnInit() { 
    this._productsService.getProducts()
        .subscribe(
          data => {this.products = data;
          this._productsService.prodcuts.next(data);
          },
          error => this.errMsg = error
        );    
}

Finally, in the child client you have to subscribe to the behavior subject declared in the service:

export class ChildComponent implements OnInit {
public products = [];

constructor(private _productsService: ProductsService ) { 
}

ngOnInit() {
    this._productsService.prodcuts
    .subscribe(
      data => {
       {this.products = data;
      }
    );    
  } 
}
like image 25
m.bouali Avatar answered Sep 28 '22 03:09

m.bouali