Sanjana k
Sanjana k

Reputation: 33

how to communicate between parent and child components , in angular

parent

HTML file

<child [validatedMessage]="message" ></child>

ts file

public message = new BehaviorSubject < {} > (undefined);

public ButtonClick() {
  this.service.getDetails(Details).subscribe((result) => {
    if (result) {
      this.message.next({
        result: result
      });
    }
  })
}

child

ts file

@Input() public validatedMessage: BehaviorSubject < {} > ;

ngOnChanges() {
  this.doSomething(this.validatedMessage);
}

doSomething(validatedMessage: BehaviorSubject < {} > ) {
  alert("im in")
}

what is happening here is, the alert message comes when pages load for the first time. but I want to get an alert message when the service function API is a success.

how do I do that? I'm doing something wrong?

Upvotes: 0

Views: 612

Answers (2)

Barremian
Barremian

Reputation: 31125

I'd say you're making it unnecessarily complicated. There is no need of using a BehaviorSubject here. You could bind a plain object to the child component. And when the reference to the variable bound changes, the ngOnChanges hook would be triggered.

Try the following

Parent

public message: any;

public ButtonClick() {
  this.service.getDetails(Details).subscribe(
    (result: any) => {
      if (result) {
        this.message = JSON.parse(JSON.stringify({ result: result }));
      }
    },
    (error: any) => {
      // handle error 
    }
  );
}

Child

@Input() public validatedMessage: any;

ngOnChanges() {
  this.doSomething(this.validatedMessage);
}

doSomething(validatedMessage: any) {
  alert("im in")
}

Upvotes: 0

SiddAjmera
SiddAjmera

Reputation: 39482

The issue here is that you've initialized message in your ParentComponent only once. And the actual reference to that message BehaviorSubject doesn't change when you pass a new value down it's Observable stream.

That's the reason why the ngOnChanges on the ChildComponent only get called when the App loads and then doesn't get called when a new message is pushed down the message BehaviorSubject's Observable stream.

Accept the validatedMessage as a regular string in your ChildComponent and pass it down as an @Input prop to it using the async pipe from the template of the ParentComponent. Something like this in the ParentComponent's template:

<child [validatedMessage]="message | async" ></child>

And in the ChildComponent:

@Input() public validatedMessage: string ;

ngOnChanges() {
  this.doSomething(this.validatedMessage);
}

doSomething(validatedMessage: string) {
  alert("im in")
}

Upvotes: 2

Related Questions