Jay Prakash Thakur
Jay Prakash Thakur

Reputation: 615

To change parent variable from child component using @Output

What i want - When i click on feedback button, a feedback form with cancel & submit button should open. Once i click cancel/submit, feedback form should get closed. if i click on feedback button again, feedback form should open again.

What's happening - When i click on feedback button, a feedback form with cancel & submit button is coming. Once i click on cancel/submit, feedback form getting closed. but if i click on feedback button again, feedback form NOT opening.

What i have done - I have a button on parent component & on click calling feedback component (by default feedback page will be hidden) like this -

app.component.html

<button type="button" (click)="showFeedbackForm()">Feedback</button>

<div *ngIf="feedbackForm">
    <app-feedback (onHide)="changeHide($event)"></app-feedback>
</div>

app.component.ts

export class AppComponent {
  name = "Angular";

  feedbackForm = false;

  showFeedbackForm() {
    this.feedbackForm = true;
  }

  changeHide(val: boolean) {
    this.feedbackForm = val;
    console.log("changeHide :: ", this.feedbackForm); // this feedbackForm value is not getting updated.
  }

}

& feedback component looks like this -

feedback.component.html

<div *ngIf="feedback"> 
    <form (ngSubmit)="onSubmit()">
        <label for="fname">First name:</label>
        <input type="text" id="fname" name="fname"><br><br>
        <label for="lname">Last name:</label>
        <input type="text" id="lname" name="lname"><br><br>
        <button type="submit" value="Submit">Submit</button>
        <button type="cancel" value="cancel" (click)="closeFeedback()">Cancel</button>
    </form>
</div>

feedback.component.ts

import { Component, OnInit, Output, EventEmitter } from "@angular/core";

@Component({
  selector: "app-feedback",
  templateUrl: "./feedback.component.html",
  styleUrls: ["./feedback.component.css"]
})
export class FeedbackComponent implements OnInit {
  constructor() {}

  ngOnInit() {}

  feedback = true;
  closeFeedback() {
    this.feedback = false;
    this.setHide();
  }

  onSubmit() {
    console.log("onSubmit called");
  }

  @Output() feedbackForm = new EventEmitter<boolean>();
  setHide() {
    this.feedbackForm.emit(false);
  }

}

Here on click of feedback button 2nd time, feedback component is not getting called.

I am not sure if i am doing it right way. stackblitz link is here. Please Feel free to update.

Please help / guide me

Upvotes: 0

Views: 1528

Answers (2)

Piyush Jain
Piyush Jain

Reputation: 1986

in app.component.html

<app-feedback (feedbackForm)="changeHide($event)"></app-feedback>

only issue is that in feedback.component.ts out property is this.feedbackForm.emit(false); while you are using (onHide).

You should use feedbackForm as output property as given above.

you just need to change this line. <app-feedback (feedbackForm)="changeHide($event)"></app-feedback>

Let me know if you have any doubt.

Upvotes: 1

Dm Mh
Dm Mh

Reputation: 840

There are too many redundant and structured in a wrong way code for such an easy task. I played around a little with the provided code. The solution may look like so (some naming must be fixed, but I've left it as it was):

app.component.ts

@Component({
  selector: "my-app",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"]
})
export class AppComponent {
  name = "Angular";

  isVisible = false;

  showFeedbackForm() {
    this.isVisible = true;
  }

  changeHide() {
    this.isVisible = false;
  }
}

app.component.html

<hello name="{{ name }}"></hello>

<button type="button" (click)="showFeedbackForm()">Feedback</button>

<div>
    <app-feedback (close)="changeHide()" *ngIf="isVisible"></app-feedback>
</div>

feedback.component.ts

import { Component, Output, EventEmitter } from "@angular/core";

@Component({
  selector: "app-feedback",
  templateUrl: "./feedback.component.html",
  styleUrls: ["./feedback.component.css"]
})
export class FeedbackComponent {
  @Output() close = new EventEmitter<void>();

  onSubmit() {
    console.log("onSubmit called");
  }

  closeFeedback() {
    this.close.emit();
  }
}

feedback.component.html

<p>
    feedback works!
</p>
<div> 
    <form (ngSubmit)="onSubmit()">
        <label for="fname">First name:</label>
        <input type="text" id="fname" name="fname"><br><br>
        <label for="lname">Last name:</label>
        <input type="text" id="lname" name="lname"><br><br>
        <button type="submit" value="Submit">Submit</button>
        <button type="cancel" value="cancel" (click)="closeFeedback()">Cancel</button>
    </form>
</div>

Upvotes: 1

Related Questions