Home > Blockchain >  Detect variable from another component and pass it to different component
Detect variable from another component and pass it to different component

Time:06-18

I'm fairly new to Angular. I'm building up this application. The structure like this.

dock component --- header
               |
               --- body --- message
               |
               --- input

I want to watch if variable is changing from 'message' component. If it gets changed, I wanna do something in 'header' component. Is there any way for 'header' component to know that?

Someone told me to use event emitter, subscribe, and make observable object. I made event emitter in the 'message' component, and don't know what to do afterwards.

Thanks,

export class MessageComponent {

  @Input() message;
  @Output() connectedAgentNameEvent = new EventEmitter<string>();
  // connectedAgentName: string = "";
  // connectedAgentNameChange: Subject<string> = new Subject<string>();

  constructor() {}

  ngOnInit() {
    if (this.message.type == 'ReceivedMessage') {
      this.connectedAgentNameEvent.emit(this.message.name);
    }
  }
}

Other thing I can think of is when variable gets changed in 'message' component, then I do event emitter to 'body' component' and to 'dock' component, and finally pass it down to 'header' with @Input()

CodePudding user response:

So this is where the container/component architecture comes into play. The idea is that you have a container component which is responsible for fetching most of the data your child components need. The child components get this data, and emit any new changes, via Input and Output respectively.

So in your case then, you would define a method in your dock which will be passed down to your Message component via html ex:

  • Dock Component.ts

    myMethod(event: any) { //In here, event can be named whatever you want, and its type should be //the type of the object or data that is being sent up. any is of course a catch //all. Set your data as needed.

    }

  • Dock Component.html

    <body-component (myMethod)="myMethod($event)">

Here you are defining the output variable, which I've elected to call myMethod in the body component as well. Note the $event in the signature, this is needed.

  • Body Component.ts

    @Output() myMethod: EventEmitter = new EventEmitter()

  • Body Component.html

    <message-component (myMethod)="myMethod.emit($event)">

In here we are saying that its Output in the body component will immediately emit whatever the message comes from the message-component. This is because I am using we don't really need to do anything with the Output in the body component. If we do, we can define our own method that accepts the result, have it update it as needed, then emit.

  • Message Component.ts

Here we do it the way you have it, where we just emit the result.

CodePudding user response:

My go to method of cross component communication is Subject. To set it up, first create a service, cli: ng generate service foo. Imagine services as cross component data/function sharing pool. Then create a subject in your service by adding:

 messageSubject = new Subject;

Then go to message component, import service and define it in constructor

import { FooService} from '../../foo.service';
constructor(private fooService: FooService);

When message component is ready to emit just call next() method on subject from imported service and add your data as argument:

this.fooService.messageSubject.next(newMessage);

Now go to header component and also import your new service. After that create a new variable of type subscription and assign it your subject with subscribe method on it:

messageSubscription : Subscription;
ngOnInit(): void {
    this.messageSubscription = this.fooService.messageSubject.subscribe((newMessage) => {
      // work with recieved data here
   });
}

Now each time next method is called on your subject, everyone subscribe (header in your case) will be immediately informed and receive latest data. Bear in mind that this way you may have many subscriber listening to data all over your app with very little hussle. After you are done with subscription (when you leave the page) you should unsubscribe from your subscriptions to prevent memory leakages. For that just add ngOnDestroy lifecycle hook:

ngOnDestroy(): void {
     this.messageSubscription.unsubscribe()
}

I understand this may be a lot to digest but if you are planning to use angular, the sooner you learn services and subjects, the better.

  • Related