1
resposta

Erro ao "setar" foco no login

Minha aplicação está apresentando erro ao tentar setar o foco no login, dentro no ngOnInit().

core.js:6189 ERROR TypeError: Cannot read property 'nativeElement' of undefined
    at SignInComponent.ngOnInit (signin.component.ts:27)
    at callHook (core.js:4690)
    at callHooks (core.js:4654)
    at executeInitAndCheckHooks (core.js:4595)
    at refreshView (core.js:11875)
    at refreshDynamicEmbeddedViews (core.js:13220)
    at refreshView (core.js:11880)
    at refreshComponent (core.js:13295)
    at refreshChildComponents (core.js:11586)
    at refreshView (core.js:11909)
import { Component, OnInit, ElementRef, ViewChild } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { AuthService } from 'src/app/core/auth/auth.service';
import { Router } from '@angular/router';
import { PlatformDetectorService } from 'src/app/core/platform-detector/platform-detector.service';

@Component({
    templateUrl: './signin.component.html'
})
export class SignInComponent implements OnInit {

    loginForm: FormGroup;
    @ViewChild('userNameInput') userNameInput: ElementRef<HTMLInputElement>;

    constructor(
        private formBuilder: FormBuilder,
        private authService: AuthService,
        private router: Router,
        private platformDetectorService: PlatformDetectorService
    ) { }

    ngOnInit(): void {
        this.loginForm = this.formBuilder.group({
            userName: ['', Validators.required],
            password: ['', Validators.required]
        });
        this.platformDetectorService.isPlatformBrowser() && 
    this.userNameInput.nativeElement.focus();
}

    login() {
        const userName = this.loginForm.get('userName').value;
        const password = this.loginForm.get('password').value;
        this.authService
            .authenticate(userName, password)
            .subscribe(
                () => this.router.navigate(['user', userName]),
                err => {
                    console.log(err);
                    alert('Invalid user name or password!');
                    this.loginForm.reset();
                    this.platformDetectorService.isPlatformBrowser() &&
                        this.userNameInput.nativeElement.focus();
                }
            );
    }
}
<h4 class="text-center">Login</h4>

<form [formGroup]="loginForm" class="form mt-4" (submit)="login()">

    <div class="form-group">
        <input #userNameInput
            formControlName="userName"
            class="form-control" 
            placeholder="user name" 
            autofocus>
        <ap-vmessage *ngIf="loginForm.get('userName').errors?.required"
            text="User name is required!">
        </ap-vmessage>
    </div>

    <div class="form-group">
        <input formControlName="password"
            type="password" 
            class="form-control" 
            placeholder="password">
        <ap-vmessage *ngIf="loginForm.get('password').errors?.required"
            text="Password is required!">
        </ap-vmessage>
    </div>

    <button [disabled]="loginForm.invalid"
        type="submit" 
        class="btn btn-primary btn-block">
        login
    </button>

</form>

<p>Not a user?<a [routerLink]="['signup']">Register now</a></p>

O mesmo problema ocorre no signup.

O que pode ser?

1 resposta

Fala ai Leandro, tudo bem? O ViewChild vai setar os elementos antes do ngAfterViewInit ser executado, ou seja, quando ele chamou o ngOnInit isso ainda não ocorreu, isso é o motivo do this.userNameInput dentro do ngOnInit ser undefined.

Tente trocar o ciclo de vida para o ngAfterViewInit.

Espero ter ajudado.

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software