Home > Enterprise >  Angular - Non child receiving component data is undefined when subscribed to a shared service variab
Angular - Non child receiving component data is undefined when subscribed to a shared service variab

Time:02-04

I've been trying to share data between two unrelated components and I've used the shared service approach to this. I've looked at dozens of tutorials and tried many variations of using a service, but no matter what I do, whenever I try to console.log() the received data in the receving component the console log dispays nothing.

The service:

import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class StatusBoxService 
{   
  private messageSource = new Subject<any>();
  currentMessage = this.messageSource.asObservable();

  constructor() {}
  
  changeMessage(message: any)
  {
    this.messageSource.next(message);
  }

}

The supplying component:

import { Component, OnInit, OnDestroy } from '@angular/core';
import { Subject, Subscription } from 'rxjs';
import { StatusBoxService } from '../../services/status-box.service';

@Component({
  selector: 'app-live-summary',
  templateUrl: './live-summary.component.html',
  styleUrls: ['./live-summary.component.css']
})

export class LiveSummaryComponent implements OnInit 
{

constructor(private data: StatusBoxService) { }

  ngOnInit(): void 
  {
     this.data.changeMessage('hello world')   
  }

  ngOnDestroy(): void
  {
    //this.subscription.unsubscribe();
  }
}

The receiving component

import { Component, OnInit } from '@angular/core';
import { FormBuilder } from '@angular/forms';
import { MatDialog, MatDialogRef } from '@angular/material/dialog';
import { Subscription } from 'rxjs';
import { StatusBoxService } from 'src/app/services/status-box.service';
import { ConfirmActionComponent } from '../confirm-action/confirm-action.component';

@Component({
  selector: 'app-delete-status-box',
  templateUrl: './delete-status-box.component.html',
  styleUrls: ['./delete-status-box.component.css']
})
export class DeleteStatusBoxComponent implements OnInit {

  subscription!: Subscription;
  selectedDevice = '';
  testy!: any;

  constructor(private form: FormBuilder, public dialog: MatDialog, private dialogRef: MatDialogRef<DeleteStatusBoxComponent>, private data: StatusBoxService) 
  {
    //this.data.currentMessage.subscribe(param => this.testy = param) // doesn't work
    this.subscription = this.data.currentMessage.subscribe((data: any) => 
      {
        this.testy = data;
      }); // doesn't work
  }

  DeleteStatusBoxForm = this.form.group({
    selectedDevice: ['']
  });

  ngOnInit() 
  {
    console.log(this.testy);
  }

  deleteStatusBox()
  {
    this.dialog.open(ConfirmActionComponent)
    //this.dialogRef.close();
  }
}

In the receiving component I print out the testy variable which I assign to the incoming data when I subscribe to the currentMessage variable in the service.

Bur somehow when I console.log() the testy variable it displays undefined and I don't know why:

enter image description here

How Components Interact:

The app-live-summary component is a page that is part of a <router-outlet></router-outlet> with other pages. The app-live-summary contains muliple other components.

One of those components contained inside the app-live-summary page is a app-header. This app-header component contains a button that when clicked opens up the app-delete-status-box component in the form of a modal pop up box.

The app-live-summary component also has some data which I would like to pass to pass to the app-delete-status-box when the button is clicked.

CodePudding user response:

if your components used in this order:

<app-delete-status-box></app-delete-status-box>
<app-live-summary></app-live-summary>

you won't get any data since you're sending a value after app-delete-status-box component is instantiated and trying to console it on ngOnInit method which will only fire when your component is being initialized on view. Try to change the order and console the value changes on inside your subscription:

ngOnit(){
 this.subscription = this.data.currentMessage.subscribe((data: any) => 
      {
        this.testy = data;
        console.log(this.testy)
      });
}

CodePudding user response:

I think that the component has not a good loading sequence. If you move "console.log" in

this.subscription = this.data.currentMessage.subscribe((data: any) => 
  {
    this.testy = data;
    console.log(this.testy);
  });

It's works ?

In view, you can use AsyncPipe to get result with observable.

{{ testy$ | async }}
  •  Tags:  
  • Related