Angular Registration page does not load after adding methods & services - html

I created an email authentication based registration page in my angular app, added the code with submission functionality (onSubmit) to register.component.html and the methods & services in register.component.ts & UserService.ts files.
Problem:
After adding the code as shared below, the registration page (register.component.html) itself does not load when I click the corresponding router link;
the issue is not with routing as it all worked fine until I added the methods & services.
No error thrown at time of compilation.
Pls suggest what to do.
Showing my respective files in register component:
register.component.html
<style>
.form-container {
display: flex;
align-items: center;
justify-content: center;
height: 50vh;
flex-wrap: wrap;
margin-top:25px;
}
.form-row {
display: flex;
flex-wrap: nowrap;
}
.form-group {
flex: 1;
margin: 20px;
}
</style>
<div class="registrationForm" type="FormGroup">
<form (ngSubmit)="onSubmit()">
<div class="form-row">
<div class="form-group">
<label for="exampleInputUsername">Username</label>
<input type="text" class="form-control" id="exampleInputUsername" placeholder="eg. Niti Sara">
</div>
<div class="form-group">
<label for="exampleInputEmail1">Email:</label>
<input type="email" [(ngModel)]="email" name="email" required class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" placeholder="eg. john#doe.com">
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="exampleInputPhone">Phone No.</label>
<input type="number" class="form-control" id="exampleInputPhone" placeholder="eg. +1300 400 5000" >
</div>
<div class="form-group">
<label for="exampleInputUrl">Website URL</label>
<input type="link" class="form-control" id="exampleInputUrl" placeholder="eg. https://example.com/">
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="exampleInputCname">Your Organisation</label>
<input type="text" class="form-control" id="exampleInputCname" placeholder="eg. Enter Your Organisation Name">
</div>
</div>
<div class="form-row">
<label>Password:</label>
<input type="password" [(ngModel)]="password" name="password" required>
</div>
<button type="submit" class="btn btn-primary" style="margin-left:220px;margin-top:20px;">Submit</button>
</form>
</div>
register.component.ts
import { Component, OnInit } from '#angular/core';
import { Router } from '#angular/router';
import { UserService } from 'src/app/register/UserService'; //import the user service
import { FormBuilder, FormGroup, Validators } from '#angular/forms'; //import form modules
#Component({
selector: 'app-register',
templateUrl: './register.component.html',
styleUrls: ['./register.component.less']
})
export class RegisterComponent implements OnInit {
registrationForm: FormGroup;
email:string ='';
password:string ='';
submitted = false;
constructor(
private formBuilder: FormBuilder,
private router: Router,
private userService: UserService,
)
{
this.registrationForm = this.formBuilder.group({});
}
ngOnInit() {
this.registrationForm = this.formBuilder.group({
email: [this.email, [Validators.required, Validators.email]],
password: [this.password, [Validators.required, Validators.minLength(6)]],
});
}
// convenience getter for easy access to form fields
get f() { return this.registrationForm.controls; }
onSubmit() {
this.submitted = true;
if (this.registrationForm.invalid) {
return;
}
//call the user service to register the user
this.userService.register(this.registrationForm.controls['email'].value, this.registrationForm.controls['password'].value)
.subscribe(data => {
// handle the response
});
//error handling can b introduced
}
}
UserService.ts
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { Observable } from 'rxjs';
#Injectable({
providedIn: 'root'
})
export class UserService {
private baseUrl = 'http://localhost:8080/'; // replace with your backend URL
constructor(private http: HttpClient) { }
//check the use of 'Observable'
register(email: string, password: string): Observable<any> {
const data = {
email: email,
password: password
};
return this.http.post(`${this.baseUrl}/register`, data);
}
}
This is what my browser console says:
ERROR Error: Uncaught (in promise): NullInjectorError: R3InjectorError(AppModule)[FormBuilder -> FormBuilder -> FormBuilder]:
NullInjectorError: No provider for FormBuilder!

Just import HttpClientModule in your app.module.ts. That's the only problem I can see here.

The problem was due to not adding FormsModule & ReactiveFormsModule in both app.module.ts & register.component.spec.ts
app.module.ts
import { FormsModule } from '#angular/forms';
import { ReactiveFormsModule } from '#angular/forms';
imports: [
FormsModule,
ReactiveFormsModule
],
register.component.spec.ts
import { FormsModule } from '#angular/forms';
import { ReactiveFormsModule } from '#angular/forms';
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ RegisterComponent ],
imports: [
FormsModule, // << ----- add this line
ReactiveFormsModule // << ----- add this line
]
})

Related

The Validators And Errors Are Not Working In Angular 9

I have started working on Angular 9 and I am using the Reactive Form in Angular 9 but the problem is that the validators and errors are not working for the form.
This is my app.module.ts:
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { FormsModule, ReactiveFormsModule } from '#angular/forms';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
#NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AppRoutingModule,
FormsModule,
ReactiveFormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
This is my app.component.ts:
import { Component, OnInit } from '#angular/core';
import { FormGroup, FormControl, Validators, FormBuilder } from '#angular/forms';
import { MustMatch } from './_helpers/must-match.validator';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
title = 'my-assignment';
submitted = false;
show: boolean;
profileForm: FormGroup;
constructor(private fb: FormBuilder) {
this.show = true;
}
ngOnInit() {
this.profileForm = this.fb.group({
email: ['', [Validators.required, Validators.pattern('[a-z0-9.#]*')]],
password: ['', [Validators.required, Validators.minLength(8)]],
confirmpassword: ['', Validators.required],
}, {
validator: MustMatch('password', 'confirmpassword')
});
}
get f() { return this.profileForm.controls; }
onSubmit() {
// TODO: Use EventEmitter with form value
console.warn(this.profileForm.value);
}
// click event function toggle
password() {
this.show = !this.show;
}
}
This is my app.component.html:
<div class="jumbotron">
<div class="container">
<div class="row">
<div class="col-md-6 offset-md-3">
<form style="margin-top: 100px;" [formGroup]="profileForm" (ngSubmit)="onSubmit()">
<div class="form-group">
<label for="firstName">Email: </label>
<input type="text" placeholder="Email" formControlName="email">
<div *ngIf="f.email.hasError('pattern')">
Oops, wrong pattern buddy!
</div>
</div>
<div class="form-group">
<label for="password">Password: </label>
<input [type]="show ? 'text' : 'password'" placeholder="Password" formControlName="password">
<div *ngIf="submitted && f.password.errors" class="invalid-feedback">
<div *ngIf="f.password.errors.required">Password is required</div>
<div *ngIf="f.password.errors.minlength">Password must be at least 6 characters</div>
</div>
</div>
<div class="form-group">
<label for="confirmpassword">Confirm Password: </label>
<input type="password" placeholder="Confirm Password" formControlName="confirmpassword" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.confirmPassword.errors }" />
<div *ngIf="submitted && f.confirmpassword.errors" class="invalid-feedback">
<div *ngIf="f.confirmpassword.errors.required">Confirm Password is required</div>
<div *ngIf="f.confirmpassword.errors.mustMatch">Passwords must match</div>
</div>
</div>
<button (click)="password()">Show Password</button>
<button type="submit" [disabled]="!profileForm.valid">Submit</button>
</form>
</div>
</div>
</div>
</div>
This is my must-match.validator.ts:
import { FormGroup } from '#angular/forms';
// custom validator to check that two fields match
export function MustMatch(controlName: string, matchingControlName: string) {
return (formGroup: FormGroup) => {
const control = formGroup.controls[controlName];
const matchingControl = formGroup.controls[matchingControlName];
if (matchingControl.errors && !matchingControl.errors.mustMatch) {
// return if another validator has already found an error on the matchingControl
return;
}
// set error on matchingControl if validation fails
if (control.value !== matchingControl.value) {
matchingControl.setErrors({ mustMatch: true });
} else {
matchingControl.setErrors(null);
}
};
}
core.js:6185 ERROR TypeError: Cannot read property 'errors' of undefined
Any help is much appreciated.
You have a typo : confirmPassword ( *ngIf="f.confirmPassword.errors.required").
It's confirmpassword everywhere else.

After clicking on button popup not showing in angulr6 project

I am doing project in angular6. I have created registration form, and I have called two functions at a time, one function for form submit, and other for open popup,as shown in the code. After clicking on submit button, the form values need to be show in popup, with final submit button, but here after clicking on submit button form getting submit but popup not getting open. I am not getting where I have done mistake. Any help please
registration.html
In this file I have called two functions at a time.
<nav class="navbar navbar-expand-lg">Header
</nav>
<div class="container">
<form [formGroup]="addForm" (ngSubmit)=[onSubmit(addForm.value),openModal()]>
<h2 class="text-center mt-3">Registration Form</h2>
<div class="card-header mt-3 mb-3">Student Registration</div>
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<label for="usn"><strong>USN</strong></label>
<input type="usn" formControlName="usn" placeholder="usn" name="usn" class="form-control" id="usn">
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label for="firstName"><strong>First Name</strong></label>
<input type="firstName" formControlName="firstName" placeholder="FirstName" name="firstName" class="form-control" id="firstName" ngModel>
</div>
</div>
</div>
<button class="btn btn-success mx-auto d-block" >Submit</button>
</div>
registration.ts
import { Component, OnInit } from '#angular/core';
import {FormBuilder, FormGroup, Validators} from "#angular/forms";
import {Router} from "#angular/router";
import {Inject} from '#angular/core';
import {MatDialog, MatDialogRef, MAT_DIALOG_DATA} from '#angular/material';
import { DisplayDataComponent } from '../display-data/display-data.component';
#Component({
selector: 'app-student-parent-registration',
templateUrl: './student-parent-registration.component.html',
styleUrls: ['./student-parent-registration.component.css']
})
export class StudentParentRegistrationComponent implements OnInit {
constructor(private formBuilder: FormBuilder, private router: Router, public dialog: MatDialog) { }
addForm: FormGroup;
ngOnInit() {
console.log("ngOnInit called")
this.addForm = this.formBuilder.group({
usn:[''],
firstName:['']
});
}
onSubmit(data) {
console.log(data);`
openModal(){
console.log("calling")
const dialogRef = this.dialog.open(DisplayDataComponent, {
width: '250px',
});
dialogRef.afterClosed().subscribe(result => {
console.log('The dialog was closed');
});
}
}
app.module.ts
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import {FormsModule, ReactiveFormsModule} from '#angular/forms';
import { FormGroup } from '#angular/forms';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { StudentParentRegistrationComponent } from './student-parent-registration/student-parent-registration.component';
import { BsDatepickerModule } from 'ngx-bootstrap/datepicker';
import { DisplayComponent } from './display/display.component';
import { DisplayDataComponent } from './display-data/display-data.component';
import {MatDialogModule} from '#angular/material/dialog';
import { BrowserAnimationsModule } from '#angular/platform-browser/animations';
#NgModule({
declarations: [
AppComponent,
StudentParentRegistrationComponent,
DisplayComponent,
DisplayDataComponent
],
imports: [
BrowserModule,
AppRoutingModule,
FormsModule,
ReactiveFormsModule,
MatDialogModule,
BrowserAnimationsModule,
BsDatepickerModule.forRoot()
],
entryComponents: [
DisplayDataComponent
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
After clicking on button not getting popup
Seems like you are not closing your form tag

my 'ngSubmit' sometimes error

so I have this html code.. i tried using (click) function, and its still like this
<div class="container">
<h1><a [routerLink]="['/databuku']"><img src="images/images.png" width="42" height="42"></a>
Add New Book</h1>
<div class="row">
<div class="col-md-6">
<form (ngSubmit)="saveBuku()" #bukuForm="ngForm">
<div class="form-group">
Judul
<input type="text" class="form-control" [(ngModel)]="buku.judul" name="judul" required>
</div>
<div class="form-group">
Author
<input type="text" class="form-control" [(ngModel)]="buku.author" name="author" required>
</div>
<div class="form-group">
Description
<textarea class="form-control" [(ngModel)]="buku.description" name="description" required cols="40" rows="5"></textarea>
</div>
<div class="form-group">
<button type="submit" class="btn btn-success" [disabled]="!bukuForm.form.valid">Save</button>
</div>
</form>
</div>
</div>
</div>
here is my ts file
import { Component, OnInit } from '#angular/core';
import { Router } from '#angular/router';
import { HttpClient } from '#angular/common/http';
#Component({
selector: 'app-tambah-buku',
templateUrl: './tambah-buku.component.html',
styleUrls: ['./tambah-buku.component.css']
})
export class ComponentTambahBuku implements OnInit {
buku = {};
constructor(private http: HttpClient, private router: Router) { }
ngOnInit() {
}
saveBuku() {
this.http.post('http://localhost:8080/buku', this.buku)
.subscribe(res => {
let id = res['id'];
this.router.navigate(['/detail-buku/', id]);
}, (err) => {
console.log(err);
}
);
}
}
no errors found when I open localhost:4200, its just when i press the save button, its like the button doesn't working, not saving and not going to 'detail-buku' page

Angular data ist not defined

simple question, I try to implement a login form and store it into the variable "data". But the console tells me ERROR ReferenceError: data is not defined.
But I did defined it. What did I do wrong?
Loginform.component.ts:
import { Component, OnInit } from '#angular/core';
import { UserService } from '../user.service';
import { Router } from '#angular/router';
#Component({
selector: 'app-loginform',
templateUrl: './loginform.component.html',
styleUrls: ['./loginform.component.css']
})
export class LoginformComponent implements OnInit {
data = {};
constructor(private router:Router, private user:UserService) { }
ngOnInit() {
}
formSubmit() {
if(data.username == 'admin' && data.passwd == 'test'){
user.setUserLoggedIn();
this.router.navigate(['dashboard']);
}
};
}
loginform.component.html:
<div class="loginFlexCenter">
<div class="loginForm">
<h2> Studienverlaufsplan Login </h2>
<hr>
<form class="inputDiv" (ngSubmit)="formSubmit()">
<div class="inputDiv">
<label>Username:</label>
<input class="txtInput" type="text" name="username" [(ngModel)]="data.username"><br/>
</div>
<div class="inputDiv">
<label>Password:</label>
<input class="txtInput" type="password" name="password" [(ngModel)]="data.passwd">
</div>
<div class="inputDivHalf">
<input class="txtInput" type="submit" value="Submit"/>
<input routerLink="/register" routerLinkActive="active" class="txtInput" type="submit" value="Register"/>
</div>
</form>
</div>
</div>

How to connect the form in angular routing

i have added angular routing to my crud operation.. before without routing the data i added was able to display in the table but now after implementation of routing the data is not getting stored in the table
here is the code of createemployee.component.html
<h2>Add Employee:</h2>
<form class="form-horizontal" #empForm="ngForm">
<div class="form-group">
<label class="control-label col-sm-2" for="name">Name:</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="name" minlength="4" maxlength="10" pattern="^[A-Za-z0-9]*[A-Za-z0-9][A-Za-z0-9]\S*$" [(ngModel)]="model.name" placeholder="Enter Your Name"
#name="ngModel" required/>
<div *ngIf="name.invalid && (name.dirty || name.touched)" class="alert alert-danger">
<div *ngIf="name.errors.required">
Name is required.
</div>
<div *ngIf="name.errors.pattern">
No Spaces
</div>
<div *ngIf="name.errors.minlength">
Name must be at least 4 characters long.
</div>
</div>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="position">Position:</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="position" minlength="4" maxlength="10" pattern="^[a-z]*$" [(ngModel)]="model.position" placeholder="Enter your position"
#position="ngModel" required />
<div *ngIf="position.invalid && (position.dirty || position.touched)" class="alert alert-danger">
<div *ngIf="position.errors.required">
Position is required.
</div>
<div *ngIf="position.errors.pattern">
Only Alphabets are must be entered
</div>
<div *ngIf="position.errors.minlength">
Position must be at least 4 characters long.
</div>
</div>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="salary">Salary:</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="salary" pattern="[0-9]*"
minlength="5" maxlength="7" [(ngModel)]="model.salary" placeholder="Enter Salary" #salary="ngModel" required />
<div *ngIf="salary.invalid && (salary.dirty || salary.touched)" class="alert alert-danger">
<div *ngIf="salary.errors.required">
Salary is required.
</div>
<div *ngIf="salary.errors.minlength">
Salary must be in 5 numbers.
</div>
<div *ngIf="salary.errors.maxlength">
Salary must not be exceeded morethan 7 numbers.
</div>
<div *ngIf="salary.errors?.pattern">Only numebers should be typed
</div>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-default" routerLink="../viewemployee" [disabled]="empForm.invalid">Add Employee</button>
<button type="button" class="btn btn-default" routerLink="../home">Cancel</button>
</div>
</div>
</form>
createemployee.component.ts
import { Component, OnInit } from '#angular/core';
import { FormControl, FormGroup , Validators} from '#angular/forms';
import { FormsModule, ReactiveFormsModule } from '#angular/forms';
#Component({
selector: 'app-createemployee',
templateUrl: './createemployee.component.html',
styleUrls: ['./createemployee.component.css']
})
export class CreateemployeeComponent implements OnInit {
model: any = {};
model2: any = {};
add=false;
create=true;
ngOnInit() {
this.model = new FormGroup({
'name': new FormControl(this.model.name,
[Validators.required, Validators.minLength(4),]),
'position': new FormControl(this.model.position,
[Validators.required, Validators.minLength(4),]),
'salary': new FormControl(this.model.salary, Validators.required)
});
}
employees = [{name: "Sunil", position: "Developer", salary: 20000},
{name: "Vamshi", position: "Java Developer", salary: 30000},
{name: "Chethan", position: ".Net Developer", salary: 10000}];
createEmp(){
this.add=true;
this.create=false;
this.Show=false;
this.edit=false;
}
addEmployee() {
this.employees.push(this.model);
this.Show = true;
this.add = false;
this.model = {};
}
}
viewemployeecomponent.ts
<h2>Employee Details</h2>
<table class="table table-bordered">
<thead>
<tr>
<th width=400>Name</th>
<th width=400>Position</th>
<th width=200>Salary</th>
<th width=400>Actions</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let employee of employees; let i=index">
<td>{{employee.name}}</td>
<td>{{employee.position}}</td>
<td>{{employee.salary}}</td>
<td>
<a class="btn btn-success" (click)="editEmployee(i)">Edit</a>
<a class="btn btn-danger" (click)="deleteEmployee(i)">Delete</a>
</td>
</tr>
</tbody>
</table>
app.router.ts
import { ModuleWithProviders } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { AppComponent } from './app.component';
import { HomeComponent } from './home/home.component';
import { CreateemployeeComponent } from './createemployee/createemployee.component';
import { ViewemployeeComponent } from './viewemployee/viewemployee.component';
import { UpdateemployeeComponent } from './updateemployee/updateemployee.component';
export const router: Routes = [
{ path: '',redirectTo: 'home',pathMatch: 'full'},
{ path: 'createemployee', component: CreateemployeeComponent },
{ path: 'updateemployee', component: UpdateemployeeComponent},
{ path: 'viewemployee', component: ViewemployeeComponent },
{ path: 'home', component: HomeComponent},
{ path: 'appcomponent', component: AppComponent}
];
export const routes: ModuleWithProviders = RouterModule.forRoot(router)
where did i have done the mistake.. i am trying to add the created employee into existing table with all other 3 hard coded employees
form what i ca see your problem is you're pushing a new employee in a component ..but you render the employee table in another and i see yours employee array is not from a service or from a #input() directive ...
so for example create a service like:
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { Observable } from 'rxjs/Rx';
import { environment } from '../../../../environments/environment';
import { PraticheGridVM, PraticheDTO } from 'app/awards/shared/models';
#Injectable()
export class EmployeeService {
private employees = [{name: "Sunil", position: "Developer", salary: 20000},
{name: "Vamshi", position: "Java Developer", salary: 30000},
{name: "Chethan", position: ".Net Developer", salary: 10000}];
constructor(private http: HttpClient) { }
/**
* Get Pratiche Mese Paginate
* #param {PraticheGridVM} filter
* #returns {Promise<Array<PraticheDTO>>}
* #memberof PraticheService
*/
public GetEmployee(): Array<Employee> {
return this.employees;
}
/**
* Get Pratiche Trimestre Paginate
* #param {PraticheGridVM} filter
* #returns {Promise<PraticheDTO>}
* #memberof PraticheService
*/
public AddEmployee(emp: Employee): Array<Employee> {
return this.employees.push(emp);
}
}
and then use it in your components .. like:
import { Component, OnInit } from '#angular/core';
import { FormControl, FormGroup , Validators} from '#angular/forms';
import { FormsModule, ReactiveFormsModule } from '#angular/forms';
import {EmployeeService} from 'yourservicePATH'
#Component({
selector: 'app-createemployee',
templateUrl: './createemployee.component.html',
styleUrls: ['./createemployee.component.css']
})
export class CreateemployeeComponent implements OnInit {
model: any = {};
model2: any = {};
add=false;
create=true;
constructor(private employeeService: EmployeeService){
}
ngOnInit() {
this.model = new FormGroup({
'name': new FormControl(this.model.name,
[Validators.required, Validators.minLength(4),]),
'position': new FormControl(this.model.position,
[Validators.required, Validators.minLength(4),]),
'salary': new FormControl(this.model.salary, Validators.required)
});
}
employees = [{name: "Sunil", position: "Developer", salary: 20000},
{name: "Vamshi", position: "Java Developer", salary: 30000},
{name: "Chethan", position: ".Net Developer", salary: 10000}];
createEmp(){
this.add=true;
this.create=false;
this.Show=false;
this.edit=false;
}
addEmployee() {
this.employeeService.AddEmployee(this.model);
this.Show = true;
this.add = false;
this.model = {};
}
}