1

I have a main component with 3 sub-components.

Main component HTML structure looks like this:

<div class="container-fluid">
   <div class="row">
      <reserved-parking></reserved-parking>

      <available-parking></available-parking>

      <profile></profile>
   </div>
</div>

For instance, when a user selects parking from available-parking component information should be sent to reserved-parking component. So, I need to pass a JSON object from available-parking to reserved-parking component.

I've tried to use @Input, but no luck. Only from parent to child and vice-versa.

Thanks in advance.

burjulius
  • 279
  • 3
  • 17

2 Answers2

8

Use event emitters and two-way binding like this.

parent component

@Component(){
...
}
export class ParentComp{
  parkingLots: Array<any> =  [one,two,three];
  constructor(){}
}

parent template

<div class="container-fluid">
   <div class="row">
      <reserved-parking [(data)]="parkingLots"></reserved-parking>

      <available-parking [(data)]="parkingLots"></available-parking>

      <profile></profile>
   </div>
</div>

reserved-parking component

@Component(){
selector: 'reserved-parking',
inputs: ['data'],
outputs: ['dataChange'],
...
}
export class ReservedParking{
  data: Array<any>;
  dataChange: EventEmitter<Array<any>> = new EventEmitter();

  constructor(){}

  ngOnInit() {
    this.data.push('four');
    this.dataChange.emit(this.data);
  }
}

available-parking component

@Component(){
selector: 'available-parking',
inputs: ['data'],
outputs: ['dataChange'],
...
}
export class AvailableParking{
  data: Array<any>;
  dataChange: EventEmitter<Array<any>> = new EventEmitter();

  constructor(){}

  ngOnInit() {
    console.log(this.data);
   // you can also update it here and then do      
   // this.dataChange.emit(this.data); to send it out
  }
}

note: import anything required, data is arbitrary change it according to your needs, main thing is to emit the value after modification by doing dataChange.emit(this.data)

Ankit Singh
  • 24,525
  • 11
  • 66
  • 89
3

@Input API can be used when you have parent-child scenario and sending data from parent to child. But here, you are having sibling components. EventEmitter can be used but over the time it becomes complex.
I'd suggest to use sharedService with subject from Rxjs library.

NOTE: Please bear with Naming Convention for this example.

https://plnkr.co/edit/7A21ofKNdi0uvbMgLUDZ?p=preview

sharedService.ts (with subject)

import {Injectable} from 'angular2/core';
import { Subject }    from 'rxjs/Subject';

@Injectable()
export class sharedService {

    private parkingType = new Subject<string[]>();
    parkingType$ = this.parkingType.asObservable();

    ParkingType(jsonData){
     console.log(jsonData);
      this.parkingType.next(jsonData);
    }

} 

availableParking.ts

import {Component} from 'angular2/core';
import {sharedService} from 'src/sharedService';

@Component({
  selector: 'navbar',
  template: `
   <h1> Available parking </h1>
   <button (click)="send()">Send Json Object</button>
  `
})
export class availableParking{
  myjson=[{"parkingType":"free parking"},{"parkingType":"paid parking"}];
  constructor(private ss: sharedService) {}

  send()
  {
     console.log(this.myjson);
    this.ss.ParkingType(this.myjson);
  }
}

reservedParking.ts

import {Component,Injectable} from 'angular2/core';
import {sharedService} from 'src/sharedService';
import {someService} from 'src/someService';
import 'rxjs/Rx';
@Component({
  selector: 'thecontent',
    template: `
    <h1>Reserved parking</h1>
    {{myjson|json}}
    `
})
export class reservedParking{
  myjson:string[];
  constructor(private ss: sharedService) {
    ss.parkingType$.subscribe((res)=>this.myjson=res); 
  }
}
micronyks
  • 54,797
  • 15
  • 112
  • 146