9
votes

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)

2
You can not pass variables from a component in other component that you have in a router-outlet. You must use a service to share data. A service is the same along the "app live" in angular.io/guide/… you have as comunicate parent and children, but if the only you want to do is more simple stackoverflow.com/questions/44914707/…Eliseo
A resolver is a service, and it is done specifically for that purpose: angular.io/guide/router#resolve-guardAyyash

2 Answers

10
votes

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

4
votes

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;
      }
    );    
  } 
}