-2
<div class="container-fluid fill">
<app-navbar></app-navbar>
<div class="container fill">
  <div class="row padding">
    <div class="col-md-3 ">
      <app-sidebar></app-sidebar>
    </div>
    <div class="col-md-6 text-center">
     <app-menu-section></app-menu-section>
    </div>
    <div class="col-md-3 ">
     <app-cart></app-cart>
    </div>
  </div>
</div>
</div>

app-sidebar renders a category menu and when a category is Selected I want to pass the value to menu section component to render appropriate category

So how to pass the value between two components which are not parent child

codefreaK
  • 3,584
  • 5
  • 34
  • 65
  • 2
    https://angular.io/guide/component-interaction – CruelEngine May 21 '18 at 08:10
  • I am not asking for child to parent or parent to child interaction , I want to know how to transfer data between two siblings @CruelEngine I have specified not parent child explicitly – codefreaK May 21 '18 at 08:31
  • create `service` and inject into `module providers` property or you can inject into `component`.then you can share data between both component. – Sanoj_V May 21 '18 at 08:37
  • @SachinDivakar , you can use a shared service to communicate between any component (which are no way related ) – CruelEngine May 21 '18 at 12:04
  • what I want to do is.When side menu anchor tag is clicked I want to render component according to this – codefreaK May 22 '18 at 09:02

4 Answers4

0

Use an @Output Event emitter to emit the selected category from the app-sidebar component.

Then you can write an event hanlder for that in the host component.

In app-sidebar component.ts

@Output() categorySelect = new EventEmitter<any>(); //put the data type of category here.

//use this method to set the selected category
    public onSelectionChange(data): void {
       this.categorySelect.emit(data);
    }

On host.component.html file.

<div class="col-md-3 ">
  <app-sidebar (categorySelect)="onCategorySelect($event)"></app-sidebar>
  <app-menu-section [selectedCategory]="selectedCategory"></app-menu-section>
</div>

on host-component.ts file

public onCategorySelect(data): void {
 this.selectedCategory = data;
}

In app-menu-section.ts file

@Input()  selectedCategory: any;

Hope this helps. For more info read this;

Anuradha Gunasekara
  • 6,553
  • 2
  • 27
  • 37
  • Can this be done with siblings – codefreaK May 21 '18 at 08:32
  • No you can't directly pass data between siblings.(Using above method). In this approach you have to keep the data in the host component. – Anuradha Gunasekara May 21 '18 at 08:34
  • I wanted to know if there was any alternative other than to use Service that is the reason I put out the question and people are blatantly down voting it – codefreaK May 21 '18 at 08:35
  • above approach does not use a service.. In this scenario you hav e two child compoents in the parent component's template. What you have to do is take the selected item from the first child and store it in the parent component. Then you can pas that value to the second child. You do not need a service to do that – Anuradha Gunasekara May 21 '18 at 08:38
0

there are many way you can do this. I suggest you to define a get function inside the controller of your app-sidebar component, like 'getSelectedItem' that return the value of the selected item. So now you can recover the selected value at any time thanks to the binding, and you can pass the value to the other component.

Therefore, in your app-sidebar component you can define the binding

binding: {
   getSelectedValue: '='
}

In the controller you can now define the get-function

thsi.getSelectedValue = {
   // do your stuff here
   return selectedValue
}

Now the crucial passage: In the main controller (I mean the controller of the html page in which you use both component) you shoul declare a function, just to tell angular that this function exist, but it is not define here (infact we want to call the function that is declared in the component to recover the selected value). So in your controller you have just to write

this.getValue;

Now in the html page you can use your modified component in this way:

<app-sidebar get-selected-value='mainController.getValue'></app-sidebar>

(Remember the kebab notation: getSelectedItem to get-selectd-item)

This is kind of a revers binding. Infact you normally define a function in your main controller and then you pass it to your component. In this case the function is define in your component, but thanks to the binding now you can call the function getSelectedItem in your main controller calling this.getValue(); Infact the function this.getValue() is not defined in the controller, it is just declared, but it is in binding with the function getSelectedValue.

At this point you have your value and you can pass it to the other component.

Maybe this method is a bit longer than other, but I suggest to use this because in many occasion it is very useful to use this 'reverse' binding.

Giuliano
  • 26
  • 1
  • 4
0

Atlernative you can share parameter as observable in your service. Just inject service into your components and subscribe. On category select update observable and all subscribers will be informed.

export class CategoryService {
  emitter: EventEmitter;
  category$: Observable<Category>;

  constructor() { 
    this.$category = Observable.create(e => this.emitter = e);
  }

  getCategory$(): Observalbe<Category> {
    return this.$category;
  }

  selectCategory(category: Category): void {
    this.emitter.next(category)
  }   
}
0

You can do it by passing data up and down your component chain as described by Anuradha Gunasekara as long as you keep in mind that your app may become cumbersome and overly complex. Of course, it all depends on the context and what you want to create. I've made this mistake as a beginner with Angular in the past and found myself with a tangled mess to trace once things have grown.