2

I have two components basically. The first one contains Angular Material option (mat-option) to select the option from combobox. The second one is supposed to show the selected data. I have created a shared Service using Subject with the hope of passing it between them but it's no luck.

The Service

@Injectable()
export class ToothpasteService {
    toothpasteName: Subject<string>;
    toothpasteName$: Observable<any>;

    constructor() {
        this.toothpasteName = new Subject();
        this.toothpasteName$ = this.toothpasteName.asObservable();
    }
}

First Component (ToothpasteComponent.ts)

export class ToothpasteComponent implements OnInit {
  toothpastes: Toothpaste[] = [
    {value: 'to-0', viewValue: 'Toothpaste A'},
    {value: 'to-1', viewValue: 'Toothpaste B'},
    {value: 'to-2', viewValue: 'Toothpaste C'},
  ]
  constructor(private toothpasteService: ToothpasteService) { }

  onToothpasteChanged(toothpasteValue: any) {
    this.toothpasteService.toothpasteName.next(toothpasteValue);
  }

ToothpasteComponent.html

       <div class="container">
            <mat-form-field>
            <mat-label>Select your toothpaste: </mat-label>
            <mat-select>
                <mat-option *ngFor="let toothpaste of toothpastes" [value]="toothpaste.viewValue" (onSelectionChange)="onToothpasteChanged(toothpaste.viewValue)">
                    {{toothpaste.viewValue}}
                </mat-option>
            </mat-select>
            </mat-form-field>
       </div>

Second Component (HeaderComponent.ts)

export class HeaderComponent implements AfterViewChecked {
  toothpasteName: string;

  constructor(private toothpasteService: ToothpasteService) { 
  }

  ngAfterViewChecked() {
    this.toothpasteService.toothpasteName$.subscribe((toothpasteData)=>{
      this.toothpasteName = toothpasteData;
    })
  }
}

HeaderComponent.html

  <div class="justify-content-start align-items-start align-self-center">
    <p>Toothpaste Selected: {{toothpasteName}}</p>
  </div>

This does not work. Am I missing something?

OreoFanatics
  • 818
  • 4
  • 15
  • 32
  • You might have a sync problem. A good way to check that (and possibly improve your sharing service) would be to replace `Subject` by `BehaviorSubject` (read more about it [here](https://stackoverflow.com/questions/39494058/behaviorsubject-vs-observable). Doing so and telling if your `HeaderComponent` access initial data from your new `BehaviorSubject` could help identifying your problem's origin. Edit: you also should not let your `ToothpasteName` Subject public, it should be private and you should only expose the Observer and an update method. – Mozgor Feb 04 '20 at 10:46

1 Answers1

0

don't use:

toothpasteName$: Observable<any>;

instead directly create an observable and use it to subscribe

ngAfterViewChecked() {
this.toothpasteService.toothpasteName. asObservable().subscribe((toothpasteData)=>{
  this.toothpasteName = toothpasteData;
})