Hello guys, I am having difficulties trying to implement a simple login form.
@Component({
selector: "app-login",
templateUrl: "./login.page.html",
styleUrls: ["./login.page.scss"]
})
export class LoginPage implements OnInit {
constructor(private service: AuthenticationService) {}
user = {};
login() {
this.service.login();
}
onSubmit() {
console.log(this.user);
}
}
<form (ngSubmit)="onSubmit()">
<ion-item>
<ion-label position="floating">Username</ion-label>
<ion-input
type="text"
[(ngModel)]="user.username"
name="username"
></ion-input>
</ion-item>
<ion-item>
<ion-label position="floating">Password</ion-label>
<ion-input
type="text"
[(ngModel)]="user.password"
name="password"
></ion-input>
</ion-item>
<ion-button type="submit" expand="block">Sign up</ion-button>
</form>
When I click the sign up button I donāt see anything in the console. What am I missing here?
Ok just in case someone else encounters the same issue, I restarted the server and it worked just fine after relaunching the app again, weird.
sisdev
February 19, 2019, 4:11pm
3
Even if the problem is solved, I think the better way to do it is like that:
<form #user="ngForm" (ngSubmit)="onSubmit(user)">
And in your onSubmit function you can access the fields like this:
user.username or user.password.
Why is this a better way? Also with this way do I need to import an Angular component in my app.module.ts?
Hello there, following your advice I decided to use Reactive Forms instead but I am getting the following error in the console:
Canāt bind to āformGroupā since it isnāt a known property of āformā
Hereās my code:
import { Component, OnInit } from "@angular/core";
import { FormGroup, FormControl } from "@angular/forms";
import { AuthenticationService } from "../../services/authentication.service";
@Component({
selector: "app-login",
templateUrl: "./login.page.html",
styleUrls: ["./login.page.scss"]
})
export class LoginPage implements OnInit {
constructor(private service: AuthenticationService) {}
loginForm = new FormGroup({
username: new FormControl(),
password: new FormControl()
});
user = {};
onSubmit() {
console.log("submitted");
}
ngOnInit() {
//console.log("Checking");
}
}
I also imported the ReactiveFormsModule to my app.module.ts
import { ReactiveFormsModule } from "@angular/forms";
...
imports: [
BrowserModule,
IonicModule.forRoot(),
AppRoutingModule,
IonicStorageModule.forRoot(),
HttpClientModule,
ReactiveFormsModule
],
<form [formGroup]="loginForm">
<ion-item>
<ion-label position="floating">Username</ion-label>
<ion-input type="text" formControlName="username"></ion-input>
</ion-item>
<ion-item>
<ion-label position="floating">Password</ion-label>
<ion-input type="text" formControlName="password"></ion-input>
</ion-item>
<ion-button type="submit" expand="block">Sign up</ion-button>
<ion-button expand="block" color="primary" [routerLink]="['/register']"
>Register</ion-button
>
</form>
What am I doing wrong?
edit: NVM, I just had to add ReactiveFormsModule to my login.module.ts file imports instead of my app.module.ts
sisdev
February 19, 2019, 4:56pm
6
you donāt need to do it that way. that what you had was already correct. Just change your form to this:
<form #user="ngForm" (ngSubmit)="onSubmit(user)">
and in the .ts file
onSubmit(loginData) {
console.log(loginData.username);
console.log(loginData.password);
}
For simple forms like this, you donāt need neccesserly formGroups
#user=āngFormā gives you a variable for that view and makes it easer to handle the data
I see, how would you add validation this way? i.e, showing div right below the input showing the error if there is an error.
sisdev
February 19, 2019, 7:38pm
8
you can add this
<ion-button type="submit" [disabled]="!user.form.valid">Login</ion-button>
to check if the input fields are valid and in the same way you can use ngIF to show a div or a message or something else.
I did it like this:
<form #form="ngForm" (ngSubmit)="onSubmit(form)">
<ion-item>
<ion-label position="floating">Username</ion-label>
<ion-input
type="text"
name="username"
#username="ngModel"
ngModel
required
minlength="5"
maxlength="50"
></ion-input>
</ion-item>
<div *ngIf="username.touched && !username.valid">
<div *ngIf="username.errors.required">Username is required</div>
<div *ngIf="username.errors.minlength">
Username should be minimum
{{ username.errors.minlength.requiredLength }} characters
</div>
</div>
<ion-item>
<ion-label position="floating">Password</ion-label>
<ion-input
type="text"
name="password"
#password="ngModel"
ngModel
required
minlength="5"
maxlength="50"
></ion-input>
</ion-item>
<div *ngIf="password.touched && !password.valid">
<div *ngIf="password.errors.required">password is required</div>
<div *ngIf="password.errors.minlength">
password should be minimum
{{ password.errors.minlength.requiredLength }} characters
</div>
</div>
<ion-button type="submit" expand="block">Sign up</ion-button>
<ion-button expand="block" color="primary" [routerLink]="['/register']"
>Register</ion-button
>
</form>
Would you say this is a good way to implement a login form validation?
Also do you think I should use ReactiveForms for the registration form, I ask this because Iād probably need to check asynchronously if the user exist in the database or not and display a loader while checking, although this may be unnecessary.
sisdev
February 19, 2019, 8:18pm
10
I didnāt run your code but seems to be ok.
And if I remember it right, you can solve the asynchronous check with (ngModelChange) in your username input field without using ReativeForm.
Would you be able to provide an example of that? Thanks for the help BTW.
sisdev
February 19, 2019, 8:23pm
12
Iāll be at my desc in few hours and will get back to you.
meanwhile you can have a look on (ngModelChange). uncle google will help you
1 Like
sisdev
February 19, 2019, 9:33pm
13
.html
<ion-input (ngModelChange)="checkUsername(form)"
type="text"
name="username"
#username="ngModel"
ngModel
required
minlength="5"
maxlength="50"
></ion-input>
and .ts file:
checkUsername(formData) {
let username = formData.controls.username.value;
if (username.length > 5) {
console.log('Do Something with: ' + username);
}
}
cheers
So basically in this function is where I would call the server to check if the username already exists. Then I think I have to use the pending property of the formControl to show the loader image.
Thanks, appreciate it.