How does angular 12 child component pass input value to parent component?

Viewed 2141

child.html

<p>
  <mat-form-field appearance="outline">
    <mat-label>Password</mat-label>
    <input matInput required [type]="show ? 'password' : 'text'" class="input">
    <button mat-icon-button matSuffix (click)="show = !show" [attr.aria-label]="'Hide password'"
            [attr.aria-pressed]="show">
      <mat-icon matSuffix>{{show ? 'visibility_off' : 'visibility'}}</mat-icon>
    </button>
  </mat-form-field>
</p>

parent.html

  <password></password>

How to get the value of the component password without using [(ngModel)]?

4 Answers

You can use event emitter to pass data from parent to child component.

parent.html <password (getValue)="onGetValue($event)">

parent.ts

onGetValue(password: string) {
    console.log('password::' + password);
}

child.html <input type="password" (keyup)="onKeyupPassword(value)" />

child.ts

@Output() getValue: EventEmitter<string> = new EventEmitter();
onKeyupPassword(value: string) {
    this.getValue.emit(value);
}

GET VALUE In child:

local reference in HTML:

<input #childPassword matInput required [type]="show ? 'password' : 'text'" class="input">

get value of that local reference in TS:

@ViewChild(‘childPassword’) childPassword!:ElementRef<HTMLInputElement>
...
Const onChildPasswordValue = this.childPassword.nativeElement.value;

SEND VALUE FROM CHILD TO PARENT:

import { ..., EventEmitter, ..., Output } from '@angular/core'; 
....
  @Output() onNewChildPassword: EventEmitter<string> 
  = new EventEmitter();
....
    this.onNewChildPassword.emit(onChildPasswordValue);

GET VALUE IN PARENT:

parent.html

<password (onChildPasswordValue)="parentMethodGetPassword($event)"></password>

parent.ts

public parentMethodGetPassword(password: string) {

// in password you will have the child password

}

You could try the following approach:

In the Parent component typescript, you have to create a method to receive the value of the password variable like this:

export class ParentComponent {

password:string;

constructor() { } 

receiveStringValue($event) {
  this.password= $event;
 }
}

In the Parent component html put the following:

<app-child (stringValueEvent)="receiveStringValue($event)"></app-child>
<h1>{{password}}<h1>

In the Child component html put the following:

<input type="password" (keyup)="onKeyupPassword(value)"/>

In the Child component typescript (app-child selector), you should declare a stringValueEvent variable with the @Output() decorator and set it equal to a new event emitter.

export class ChildComponent {

  password:string;

  @Output() stringValueEvent = new EventEmitter<string>();

  constructor() { }

  onKeyupPassword(value: string) {
    this.password = value;
    this.stringValueEvent.emit(this.password)
  }

  ngOnInit(): void {
    
  }
}

solved

username.component.html
<p>
  <mat-form-field appearance="outline">
    <mat-label>Username</mat-label>
    <input matInput required type="text" class="input"
           [(ngModel)]="value" (keyup)="newUsername(value)">
    <button mat-icon-button matSuffix disabled>
      <mat-icon matSuffix>account_circle</mat-icon>
    </button>
  </mat-form-field>
</p>

username.compoment.ts
import { Component, EventEmitter, OnInit, Output } from '@angular/core';
import { FormControl, Validators } from '@angular/forms';

@Component({
  selector: 'username',
  templateUrl: './username.component.html',
  styleUrls: ['./username.component.scss']
})
export class UsernameComponent implements OnInit {

  constructor() {
  }

  ngOnInit(): void {
  }

  value: string = '';

  @Output() username: EventEmitter<string> = new EventEmitter();

  newUsername(value: string) {
    this.username.emit(value);
  }
}
signin.component.html
<app-header></app-header>
<form>
  <username (username)="username($event)"></username>
  <password (password)="password($event)"></password>
  <p class="button signin">
    <button mat-raised-button color="primary" type="button"
            (click)="onSubmit()" (keyup.enter)="onSubmit()">Sign in
    </button>
  </p>
</form>
<app-footer></app-footer>
signin.compoment.ts
import { Component, OnInit } from '@angular/core';
import { SigninService } from './signin.service';
import { Signin } from './signin';

@Component({
  selector: 'app-signin',
  templateUrl: './signin.component.html',
  styleUrls: ['./signin.component.scss']
})
export class SigninComponent implements OnInit {

  constructor(
    private service: SigninService
  ) {
  }

  ngOnInit(): void {
  }

  signin: Signin = {
    username: '',
    password: ''
  };

  username(value: string) {
    this.signin.username = value;
  }

  password(value: string) {
    this.signin.password = value;
  }

  onSubmit() {
    return this.service.post(this.signin);
  }

}
Related