AndreaNobili
AndreaNobili

Reputation: 42957

What is a smart solution to send information from an Angular component to another sibling component?

I am pretty new in Angular and I have a doubt about what could be a good way to allow to comunicate two components into my application. I know that exist different strategies and I want to understand what could be a good choise for my specific case.

Basically I have this situation:

enter image description here

As you can see in the previous screenshot I have two components:

So basically when I click the funnel icon in the component 1 (the people list) the following methodo into this compoenent typescript code will be executed:

onClickFilter(person, event) { console.log("onClickFilter START. person is: ", person); }

The person object is the one containing the information that I have to send to the component 2 (the calendar component on the right).

I was reading here about how allow components comunication:

https://medium.com/@mirokoczka/3-ways-to-communicate-between-angular-components-a1e3f3304ecb

and also here: https://angular.io/guide/component-interaction

But I don't know what is the best choice. In particular in the official Angular documentation I can find the way to pass from parent to child (but here these component are siblings).

An idea is to emit an event in component 1 (the people list) and subscribe it in component 2 (the calendar) but I am not sure if it is too much strongly tight.

What can be a smart solution in this use case?

The first one

Upvotes: 0

Views: 184

Answers (3)

Abdullah Mansoor
Abdullah Mansoor

Reputation: 67

Use the Input() decorator to pass the data. In your case who sends the data to another component is the parent. Who recieves the data is Child. When you need to send the data from Parent to Child we use @Input(). When we need to send the data from Child to Parent we use @OutOut() and EventEmitter.

In your case its definetely component1 is the Parent and component2 is the child.

In your component1.ts file, define the property that should pass the data to component 2. In my case let's say personDetails. And in your onclick method perform your operations and assign the detail to the personDetails property.

export class Component1  {
  personDetails: ShiftDetail;

  onClickFilter(data: any) {
    // do the logics
    this.personDetails = data;
  }
}

In your component2.ts file define a property with @Input() decorator. This property will get the detail from component1.

export class Component2  {
  @Input() personDetailsInput: ShiftDetail;
}

To assign the details from component1's property personDetails to component2's personDetailsInput, use the component1.html file. Use the property binding to assign the value.

<component2 [personDetailsInput]="personDetails"></component2>

For the reference, use the Angular official documentation. The hero villian app will define everything.

Upvotes: 2

lvndsky
lvndsky

Reputation: 159

In the situation when you want to pass the data between two components that are not in the parent-child relationship - the best solution would be to use a service and a concept of Subject.

How do we use it?

First, create data.service.ts

@Injectable({
  providedIn: 'root'
})
export class DataService {

  constructor() { }

  dataToBePassed = new Subject<any>();
  dataToBePassedObs = this.dataToBePassed.asObservable();
  
  changeData(newData: any) {
    this.dataToBePassed.next(newData);
  }

}

Then you'll need to inject this service in both components that you want to share the data between. One side will keep sending the data and the other side will listen (by subscribing).

listener-sibling.component.ts

export class ListenerSibling implements OnInit {

  someData: any;

  constructor(private dataService: DataService) { }

  ngOnInit(): void {
    this.dataService.dataToBePassedObs().subscribe((data) => {
        this.someData = data;
    })
  }

}

sender-sibling.component.ts

export class SenderComponent implements OnInit {

  constructor(private dataService: DataService) { }

  ngOnInit(): void {
  }

  sendData() {
    this.dataService.changeData('sending new data');
  }

}

Upvotes: 2

Rick
Rick

Reputation: 1870

It's unclear to me exactly how your app is set up. I see a list view of people, and a calendar view, and you are calling them "siblings", but it's not entirely clear to me how navigation is working. Here are the options I see.

  1. If both the list view and the calendar both appear on the screen at the same time, they are in fact siblings, and both would be children of a parent component. So clicks on child A can be passed up to the parent via Emit, and then passed back down to child B via ViewChild.

  2. Clicking on a user in the list view may "route" you to the calendar view, in which case using queryParams would work well to pass in the userId to the calendar

  3. Clicking on a user might bring up a popup modal, of the calendar, which means you could pass data directly from view A to view B using ViewChild. Or even skip the ViewChild and pass data directly using html tags.

Upvotes: 1

Related Questions