I have a scenerio where a pipe return the class name based on the input and my test case is getting failed if I trying to test the pipe. My implementation is as follows, can anyone pls help.Thanks.
I have a html as follows,
<div [class]="type | functionTester: getNameOfClass: this">
....
</div>
Ts,
type = 'high';
getNameOfClass() {
if (type === 'high') {
return 'HIGH';
} else {
return 'LOW';
}
}
Pipe,
export class functionTesterPipe implements PipeTransform {
public transform(
value: any,
handler: (value: any) => any,
context?: any
): any {
if (context) {
return handler.call(context, value);
}
return handler(value);
}
}
Spec,
const { find } = await shallow
render({
bind: { chartData: chartData, type: 'ORG_BENCHMARK' }
});
const pipe = new functionTesterPipe();
expect(pipe.transform('high', instance.prepareClassName)).toBe('High');
fixture.detectChanges();
expect(find('.High').length).toBe(1); -> Failing at this line as [expect 0 to be 1]
I have a scenerio where a pipe return the class name based on the input and my test case is getting failed if I trying to test the pipe. My implementation is as follows, can anyone pls help.Thanks.
Basic setup for pipe testing:
import { Pipe } from './pipe.pipe';
describe('Pipe', () => {
let pipeToTest: Pipe;
// synchronous beforeEach
beforeEach(() => {
pipeToTest = new Pipe();
});
it('should be instanciated', () => {
expect(pipeToTest).toBeDefined();
});
});
<table>
<tr>
<th>Employee Name</th>
<th>Employee ID</th>
<th>Mail</th>
<th>Salary</th>
<th>Actions</th>
<th></th>
</tr>
<tr *ngFor="let data of empolyeeDetails ">
<td> {{data?.name}} </td>
<td> {{data?.id}} </td>
<td> {{data?.email}} </td>
<td> {{data?.salary}} </td>
<td><button type="Edit" class="btn btn-primary" (click)="onEdit(data) ">Edit</button></td>
<td><button type="Delet" class="btn btn-primary" (click)="onDelete(data)">Delete</button></td>
</tr>
</table>
<br>
<div class="crudForm">
<form [formGroup]="crudForm">
<div class="form-group">
<label for="exampleInputEmail1">Name</label>
<input type="text" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp"
placeholder="Enter Name" formControlName="name">
</div>
<div class="form-group">
<label for="exampleInputEmail1">Email</label>
<input type="email" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp"
placeholder="Enter email" formControlName="email">
</div>
<div class="form-group">
<label for="exampleInputEmail1">salary</label>
<input type="text" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp"
placeholder="Enter Salary" formControlName="salary">
</div>
<!-- <div class="form-group">
<label for="exampleInputPassword1">Password</label>
<input type="password" class="form-control" id="exampleInputPassword1" placeholder="Password">
</div> -->
<button type="submit" class="btn btn-primary" (click)="onSubmit()">Submit</button>
</form>
</div>
===============================================================
import { Component } from '#angular/core';
import { FormBuilder } from '#angular/forms';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'credApp';
crudForm: any;
isEdit = false;
empolyeeDetails = [
{ name: "Ragu", id: "123", email: "rag#mail.com", salary: 50000 },
{ name: "Ramu", id: "345", email: "ram#mail.com", salary: 40000 },
{ name: "Raju", id: "678", email: "raju#mail.com", salary: 45000 }
];
constructor(public fb: FormBuilder) {
this.loadForm();
if (this.getFromLocalStorage()) {
this.empolyeeDetails = this.getFromLocalStorage();
}
}
loadForm() {
this.crudForm = this.fb.group({
name: [''],
id: [''],
email: [''],
salary: ['']
});
}
onEdit(data: any) {
this.isEdit = true;
this.crudForm.controls['name'].setValue(data.name);
this.crudForm.controls['id'].setValue(data.id);
this.crudForm.controls['email'].setValue(data.email);
this.crudForm.controls['salary'].setValue(data.salary);
}
onDelete(data: any) {
var index = this.empolyeeDetails.findIndex(function(element) {
return (element.id === data.id);
});
this.empolyeeDetails.splice(index, 1);
this.performStorageAction();
}
onSubmit() {
var randomNum = Math.floor(Math.random() * 90 + 10);
if (this.isEdit) {
this.onDelete(this.crudForm.value);
} else {
this.crudForm.controls['id'].setValue(randomNum);
}
this.empolyeeDetails.push(this.crudForm.value);
this.performStorageAction();
this.crudForm.reset();
}
storeInLocalStorage() {
localStorage.setItem("data", JSON.stringify(this.empolyeeDetails));
}
getFromLocalStorage() {
return JSON.parse(localStorage.getItem('data') || '');
}
performStorageAction() {
this.storeInLocalStorage();
this.empolyeeDetails = this.getFromLocalStorage();
}
}
Related
I have async function named save in a my component
async save(): Promise<void> {
if (!this.ValidateForm()) {
notifyError("", "Please enter all fields correctly");
}
else {
await userModule.update(userModule.currentUser?.id as number, this.user, this.file);
notifySuccess("Your profile updated");
}
}
When this line executed :
await userModule.update(userModule.currentUser?.id as number, this.user, this.file);
Value of second and third argument becomes undefined in userModule.update .
In addition i have to say i don't use any arrow function
and i tried console.log(this.user, this.file) everything is ok.
here is my code :
AccountSetting.ts HTML
<template>
<div>
<div class="row justify-content-center">
<!-- left column -->
<div class="col-md-6">
<!-- general form elements -->
<div class="card card-primary">
<div class="card-header">
<h3 class="card-title">Change your information</h3>
</div>
<!-- /.card-header -->
<!-- form start -->
<form>
<div class="card-body">
<div class="form-row">
<div class="col form-group">
<label>Username </label>
<input
type="text"
v-model="user.username"
#change="checkUsername()"
class="form-control"
placeholder="Enter new Username"
/>
<small class="validation">{{ validations.username }}</small>
</div>
<div class="col form-group">
<label>Profile Pricture </label>
<div class="custom-file">
<input
id="customFile"
type="file"
class="custom-file-input"
v-on:change="handleFileUpload($event)"
accept="image/*"
/>
<label class="custom-file-label" for="customFile">{{
lblFilename
}}</label>
</div>
</div>
</div>
<div class="form-row">
<div class="col form-group">
<label>Firstname </label>
<input
type="text"
v-model="user.firstname"
#change="checkFirstname()"
class="form-control"
placeholder="Enter your Firstname"
/>
<small class="validation">{{ validations.firstname }}</small>
</div>
<div class="col form-group">
<label>Lastname</label>
<input
type="text"
v-model="user.lastname"
#change="checkLastname()"
class="form-control"
placeholder="Enter your Lastname"
/>
<small class="validation">{{ validations.lastname }}</small>
</div>
</div>
<div class="form-row">
<div class="col form-group">
<label>Email </label>
<input
type="text"
v-model="user.email"
#change="checkEmail()"
class="form-control"
placeholder="Enter your Email address"
/>
<small class="validation">{{ validations.email }}</small>
</div>
<div class="col form-group">
<label>Phone Number</label>
<input
type="text"
v-model="user.phoneNumber"
#change="checkPhonenumber()"
class="form-control"
placeholder="Enter your Phone number"
/>
<small class="validation">{{
validations.phoneNumber
}}</small>
</div>
</div>
<div class="form-row">
<div class="col form-group">
<label>Birthdate </label>
<input
type="date"
v-model="user.birthdate"
class="form-control"
placeholder=""
/>
</div>
<div class="col form-group">
<label>Gender</label>
<div class="form-control">
<div class="form-check form-check-inline">
<label class="form-check-label pr-2" for="inlineRadioMale"
>Male</label
>
<input
id="inlineRadioMale"
type="radio"
name="gender"
value="1"
v-model="user.gender"
class="form-check-input"
checked
/>
</div>
<div class="form-check form-check-inline">
<label
class="form-check-label pl-3 pr-2"
for="inlineRadioFemale"
>Female</label
>
<input
id="inlineRadioFemale"
type="radio"
name="gender"
value="2"
v-model="user.gender"
class="form-check-input"
/>
</div>
</div>
</div>
</div>
</div>
<!-- /.card-body -->
<div class="card-footer">
<button type="button" class="btn btn-primary" #click="save()">
Save
</button>
</div>
</form>
</div>
<!-- /.card -->
</div>
</div>
</div>
</template>
AccountSetting.ts script
import { Component, Vue } from "vue-property-decorator";
import { UserUpdate } from "#/models/user/user";
import userModule from "#/store/modules/user";
import validationUtils from "#/common/validationUtils";
import { notifySuccess, notifyError } from
"#/common/notificationUtils";
import GenderType from "#/common/Enums/genderType";
import { isNullOrEmpty } from "#/common/stringUtils";
#Component
export default class AccountSetting extends Vue {
// eslint-disable-next-line #typescript-eslint/no-explicit-any
private file: any;
private lblFilename = "Choose file";
private user: UserUpdate = {
username: userModule.currentUser?.username as string,
firstname: userModule.currentUser?.firstname as string,
lastname: userModule.currentUser?.lastname as string,
email: userModule.currentUser?.email as string,
birthdate: userModule.currentUser?.birthdate as string,
phoneNumber: userModule.currentUser?.username as string,
gender: userModule.currentUser?.gender as GenderType,
teamId: userModule.currentUser?.teamId as number,
profilePictureId: userModule.currentUser?.profilePictureId as number,
};
// eslint-disable-next-line #typescript-eslint/no-explicit-any
private validations: any = {
username: "",
password: "",
firstname: "",
lastname: "",
email: "",
phoneNumber: "",
};
checkUsername(): void {
if (!validationUtils.isValidUsername(this.user.username)) {
this.validations.username = "Username is invalid";
}
else if (this.user.username.length == 0) {
this.validations.username = "Username is invalid";
}
else if (this.user.username.length > 15) {
this.validations.username = "Username should be less than 15 characters";
}
else {
this.validations.username = "";
}
}
checkEmail(): void {
if (!validationUtils.isValidEmail(this.user.email)) {
this.validations.email = "Email is invalid";
} else {
this.validations.email = "";
}
}
checkFirstname(): void {
if (this.user.firstname.length == 0) {
this.validations.firstname = "Firstname is invalid";
}
else if (this.user.firstname.length > 35) {
this.validations.firstname = "Firstname should be less than 35 characters";
}
else {
this.validations.firstname = "";
}
}
checkLastname(): void {
if (this.user.lastname.length == 0) {
this.validations.lastname = "Lastname is invalid";
}
else if (this.user.firstname.length > 35) {
this.validations.lastname = "Lastname should be less than 35 characters";
}
else {
this.validations.lastname = "";
}
}
checkPhonenumber(): void {
if (this.user.phoneNumber.length == 0) {
this.validations.phoneNumber = "Phone Number is invalid";
}
else {
this.validations.phoneNumber = "";
}
}
ValidateForm(): boolean {
this.checkUsername();
this.checkFirstname();
this.checkLastname();
this.checkEmail();
this.checkPhonenumber();
if (this.user.username == "" || !isNullOrEmpty(this.validations.userUsername)) {
return false;
}
if (this.user.firstname == "" || !isNullOrEmpty(this.validations.firstname)) {
return false;
}
if (this.user.lastname == "" || !isNullOrEmpty(this.validations.lastname)) {
return false;
}
if (this.user.email == "" || !isNullOrEmpty(this.validations.email)) {
return false;
}
if (this.user.phoneNumber == "" || !isNullOrEmpty(this.validations.phoneNumber)) {
return false;
}
return true;
}
// eslint-disable-next-line #typescript-eslint/explicit-module-boundary-types
handleFileUpload(event: any): void {
this.file = event.target.files[0];
this.lblFilename = this.file.name;
}
async save(): Promise<void> {
if (!this.ValidateForm()) {
notifyError("", "Please enter all fields correctly");
}
else {
await userModule.update(userModule.currentUser?.id as number, this.user, this.file);
notifySuccess("Your profile updated");
}
}
}
Vuex module
user.ts :
import {
Action,
getModule,
Module,
Mutation,
VuexModule
} from "vuex-module-decorators";
import modulesNames from "#/store/moduleNames";
import store from "#/store/index";
import localStorageUtils from "#/common/localStorageUtils";
import { User, UserCreate, UserUpdate } from
"#/models/user/user";
import Token from "#/models/authentication/token";
import authenticationService from
"#/services/authentication/authenticationService";
import userService from "#/services/user/userService";
import Login from "#/models/user/login";
import { isEmptyObject } from "#/common/objectUtils";
#Module({ dynamic: true, namespaced: true, store, name: modulesNames.user })
class UserModule extends VuexModule {
private _currentUser?: User = localStorageUtils.getItem("User");
private _authToken?: Token = localStorageUtils.getItem("Token");
get currentUser(): User | undefined | null {
return this._currentUser;
}
get authToken(): Token | undefined | null {
return this._authToken;
}
get isLoggedIn(): boolean {
return !isEmptyObject(this.currentUser);
}
#Mutation
private SET_CURRENT_USER(currentUser?: User): void {
if (currentUser) {
this._currentUser = currentUser;
localStorageUtils.setItem("User", currentUser);
} else {
this._authToken = undefined;
localStorageUtils.removeItem("User");
}
}
#Mutation
private SET_AUTH_TOKEN(authToken?: Token): void {
if (authToken) {
this._authToken = authToken;
localStorageUtils.setItem("Token", authToken);
} else {
this._authToken = undefined;
localStorageUtils.removeItem("Token");
}
}
#Action({ rawError: true })
public async login(login: Login): Promise<void> {
const response = await authenticationService.login(login);
this.SET_CURRENT_USER(response);
}
#Action({ rawError: true })
public async register(userCreateOrUpdate: UserCreate): Promise<void> {
const response = await authenticationService.register(userCreateOrUpdate);
this.SET_CURRENT_USER(response);
}
#Action({ rawError: true })
public async update(id: number, userUpdate: UserUpdate, file: any): Promise<void> {
const response = await userService.updateUser(id, userUpdate, file);
this.SET_CURRENT_USER(response);
}
#Action({ rawError: true })
public async logout(): Promise<void> {
await authenticationService.logout();
this.SET_AUTH_TOKEN(undefined);
this.SET_CURRENT_USER(undefined);
}
}
export default getModule(UserModule);
index.ts
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export default new Vuex.Store({
state: {},
mutations: {},
actions: {},
modules: {},
});
modulesNames.ts :
const modulesNames = {
user: "user",
};
export default modulesNames;
I'm new to javascript and typescript and frontend frameworks .
After many attempts for this problem in stackoverflow an also reading the docs
,I found nothing so i decided to do more debugging and i understand
Vuex actions only take one arguments so another arguments values becomes undefined
I need to return value of array by index, but after the variable receive the index the array below return error.
When I select for example "Diminuiu Pouco" I need to set planoCuidadosForm.controls.scorePadraoAlimentar to respective Score in array
component:
export class AppComponent {
planoCuidadosForm: FormGroup;
padraoAlimentar: any[] = [
{ Desc: "Mesmo de Sempre", Score: 1 },
{ Desc: "Diminuiu Pouco", Score: 2 },
{ Desc: "Diminuiu Pela Metade", Score: 3 },
{ Desc: "Diminuiu Muito", Score: 4 },
{ Desc: "Quase Nada", Score: 5 }
];
constructor(
private fb: FormBuilder,
) { }
onInit(){
this.createFormPlanos();
}
createFormPlanos() {
this.planoCuidadosForm = this.fb.group({
ProtocoloMedicoId: [null],
padraoAlimentar: [''],
scorePadraoAlimentar: 0
});
}
calcScoreNut() {
if (this.planoCuidadosForm == null) return;
if (this.planoCuidadosForm.get("padraoAlimentar").value !== null) {
let x = this.padraoAlimentar.indexOf(this.planoCuidadosForm.get("padraoAlimentar").value).valueOf();
console.log('Test ', this.padraoAlimentar[x].Score);
this.planoCuidadosForm.controls.scorePadraoAlimentar.setValue(
this.padraoAlimentar[x].Score
);
}
}
}
HTML:
<form class="form-horizontal ml-2 mr-2 mt-2" [formGroup]="planoCuidadosForm" >
<div class="form-row">
<div class="form-group col-md-6">
<label for="padraoalimentar">Padrão Alimentar</label>
</div>
<div class="form-group col-md-3">
<select class="form-control" id="padraoalimentar" formControlName="padraoAlimentar" (click)="calcScoreNut()">
<option value="null"> -- Selecione -- </option>
<option *ngFor="let pad of padraoAlimentar;let op = index" [value]="pad.Desc">{{ pad.Desc }}</option>
</select>
</div>
<div class="form-group col-md-3">
<div class="input-group">
<label for="scorepadraoalimentar">Score: </label>
<input type="number" formControlName="scorePadraoAlimentar" class="form-control" id="scorepadraoalimentar" [value]="planoCuidadosForm.get('scorePadraoAlimentar').value"
[attr.disabled]="true" />
</div>
</div>
</div>
</form>
https://stackblitz.com/edit/angular-vdkwvg
Your app.component must implement OnInit, and rename your onInit() method to ngOnInit().
export class AppComponent implements OnInit
I has make the change below and and the function works.
calcScoreNut() {
if (this.planoCuidadosForm == null) return;
if (this.planoCuidadosForm.get("padraoAlimentar").value !== null) {
let x = this.padraoAlimentar.find(z => z.Desc == this.planoCuidadosForm.get("padraoAlimentar").value);
this.planoCuidadosForm.controls.scorePadraoAlimentar.setValue(
x.Score
);
}
}
https://stackblitz.com/edit/angular-vdkwvg
I am creating a website which calls a list of items from an external API.
The list has an "Order" button alongside it which when pressed, opens a modal with an order form.
The form is submitted, the API correctly receives the form data. But I am trying to send the row information to the API aswell to inform what has actually been ordered.
The problem is that only the first row returned is ever sending no matter which line is "Ordered".
My html code file is:
<head>
</head>
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<div class="body">
<h1 class="header">Carpet Clearance</h1>
<h2 class="header">
The Mega Day carpet clearance list
</h2>
</div>
<table class="table">
<th>
<td>Range</td>
<td>Size</td>
<td>Colour</td>
<td>Cost</td>
<td>Value</td>
<td>Order</td>
<tr *ngFor="let row of carpet;">
<td class="td2">{{row.ID}}</td>
<td>{{row.Range}}</td>
<td>{{row.Size}}</td>
<td>{{row.Colour}}</td>
<td>{{row.Cost}}</td>
<td>{{row.Value}}</td>
<td><button onclick="document.getElementById('id01').style.display='block'" class="btn">Order Item</button>
<div id="id01" class="w3-modal">
<div class="w3-modal-content w3-animate-bottom w3-card-4">
<header class="w3-container w3-teal">
<span onclick="document.getElementById('id01').style.display='none'"
class="w3-button w3-display-topright">×</span>
<h2 class="body">Order this item</h2>
</header>
<div class="modal">
<p class="form">To order this range, please enter your customer account number, delivery address and Rep ID.</p>
<form class="form" [formGroup]="checkoutForm" (ngSubmit)="onSubmit(checkoutForm.value, row)">
<div>
<label for="Rep ID">
Rep ID<br>
</label>
<input id="Rep" type="text" formControlName="Rep">
</div>
<div>
<label for="Account">
Account Number<br>
</label>
<input id="Account" type="text" formControlName="Account">
</div>
<div>
<label for="address">
Address<br>
</label>
<input id="Address" type="text" formControlName="Address">
</div>
<button class="button" type="submit">Order</button>
</form>
</div>
</div>
</div>
</td>
</tr>
</table>
My TS file is:
import { Component, OnInit } from '#angular/core';
import { ApiService } from '../../shared/api.service';
import { FormBuilder } from '#angular/forms';
#Component({
selector: 'app-carpet',
templateUrl: './carpet.component.html',
styleUrls: ['./carpet.component.scss']
})
export class CarpetComponent implements OnInit {
checkoutForm;
carpet = [];
loadingIndicator = true;
reorderable = true;
columns = [
{ prop: 'ID', summaryFunc: () => null },
{ prop: 'Range', summaryFunc: () => null },
{ prop: 'Colour', summaryFunc: () => null },
{ prop: 'Size', summaryFunc: () => null },
{ prop: 'Cost', summaryFunc: () => null },
{ prop: 'Value', summaryFunc: () => null }
];
constructor(private apiService: ApiService,
private formBuilder: FormBuilder
) {
this.checkoutForm = this.formBuilder.group({
Rep: '',
Account: '',
Address: ''
});
}
ngOnInit() {
this.apiService.getCarpet()
.subscribe((carpet: any[]) => {
this.carpet = carpet;
this.loadingIndicator = false;
});
}
onSubmit(customerData, row) {
const data = {
customerData, row
};
this.apiService.sendFormData(data)
.subscribe();
this.checkoutForm.reset();
console.warn('Your order has been submitted', customerData);
}
}
Can anyone point me towards the error here?
I am doing a project that need to display an array and user can add in new data or delete existing data from the array.
I am stuck with how to add and delete item from array.
I tried to use push function to add and pop function to delete but failed.
HTML
<div class="write">
<h1>Student Details</h1>
<div class="data" *ngIf="selectedStudent">
<li> Name: <input type="text" [(ngModel)]="name" placeholder="Please enter Name" value={{selectedStudent.name}}>
</li>
<li> Age:<input type="text" [(ngModel)]="age" placeholder="Please enter Age" class="age"
value={{selectedStudent.age}}></li>
<li>College:<input type="text" [(ngModel)]="college" placeholder="Please enter College"
value={{selectedStudent.college}}></li>
</div>
<p>
<button class="btnA" onclick="addStudent()">Add</button>
<button class="btnE" onclick="editStudent()">Edit</button>
<button class="btnD" onclick="deleteStudent()">Delete</button>
</p>
<li *ngFor="let student of student" [class.selected]="student === selectedStudent" (click)="onSelect(student)">
<span class="badge">{{student.name}} {{student.age}} {{student.college}}</span>
</li>
</div>
.ts
export class WriteComponent implements OnInit {
name: string;
age: number;
college: string;
student = STUDENTS;
selectedStudent: Student;
constructor() {}
ngOnInit(): void {}
onSelect(student: Student): void {
this.selectedStudent = student;
}
}
mock-student.ts (where I store my array)
import { Student } from './student';
export const STUDENTS : Student[]=[
{name:'Johnny',age:24,college:'Harvard'},
{name:'Samantha',age:20,college:'INTI'},
{name:'Aditya',age:21,college:'Sunway'},
{name:'Troy',age:25,college:'TARUC'},
]
Hope this helps.....
Result:
app.component.html
<div class="container">
<h2>Add User</h2>
<form class="form-inline" autocomplete="off" (submit)="addStudent()">
<div class="form-group">
<label for="email">Name:</label>
<input type="text" class="form-control" id="name" name="name" [(ngModel)]="user.name">
</div>
<div class="form-group">
<label for="pwd">Age:</label>
<input type="number" class="form-control" id="age" name="age" [(ngModel)]="user.age">
</div>
<div class="form-group">
<label for="pwd">College:</label>
<input type="text" class="form-control" id="college" name="college" [(ngModel)]="user.college">
</div>
<button type="submit" class="btn btn-success">Submit</button>
</form>
<div class="user-list" *ngIf="usersList && usersList.length">
<h2>List of Users</h2>
<table class="table table-condensed">
<thead>
<tr>
<th>SL.No</th>
<th>Name</th>
<th>Age</th>
<th>College</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let user of usersList; let i = index">
<th>{{i}}</th>
<td>{{user.name}}</td>
<td>{{user.age}}</td>
<td>{{user.college}}</td>
<td>
<button style="margin-right: 5px;" class="btn btn-warning" (click)="editStudent(i)">Edit</button>
<button class="btn btn-danger" (click)="deleteStudent(i)">Delete</button>
</td>
</tr>
</tbody>
</table>
</div>
app.component.ts
export class AppComponent implements OnInit{
user: User;
usersList: User[] = []
ngOnInit(): void {
this.resetForm();
}
addStudent() {
this.usersList.push(this.user);
this.resetForm();
}
editStudent(index: number) {
this.user = this.usersList[index];
this.deleteStudent(index);
}
deleteStudent(index: number) {
this.usersList.splice(index, 1);
}
resetForm() {
this.user = {age: null, name: '', college: ''};
}
}
interface User {
name: string;
age: string;
college: string;
}
Deleting an item from the array
You are setting your selectedStudent to one of the instances in your array, so it is simple enough to find its index when you want to remove it from the array.
You can use the splice array function to remove the item at the index.
// declare students here for the purpose of the answer
students: Student[] = [
{name:'Johnny', age:24, college:'Harvard'}
// ... more students here
];
selectedStudent : Student;
onSelect(student:Student): void {
this.selectedStudent = student;
}
deleteStudent(): void {
if (!this.selectedStudent) {
return;
}
// find the index of the selected student
// this works because your selected student is one of the array items
// it wouldn't work if selected student was a copy
const index = this.students.indexOf(this.selectedStudent);
// use splice to remove 1 item starting at the given index
this.students.splice(index, 1);
// todo: logic to reset this.selectedStudent
}
Adding an item to the array
Adding is simple. Use the push array function to append an item to an array.
students: Student[] = [];
name: string;
age: number;
college: string;
addStudent() {
const student = {
name: this.name,
age: this.age,
college: this.college
};
this.students.push(student);
}
I'm working on an Angular and Spring Boot app and I'm very new to Angular. I've made some components, a component for login and one for register, also I've made some validation, etc. Now, what I want to do is when the user registration is successfully the user is redirected to login page and also I want to show a message like this: "Registration Successful! Please Login!" I know how to redirect the user to the login page but I don't know how to show this message for the user.
Register ts
import { Component, OnInit, ViewChild } from '#angular/core';
import { NgForm } from '#angular/forms';
import { User } from '../model/user.model';
import { UserDataService } from '../service/data/user-data.service';
import { Router } from '#angular/router';
#Component({
selector: 'app-register',
templateUrl: './register.component.html',
styleUrls: ['./register.component.css']
})
export class RegisterComponent implements OnInit {
invalidRegister = false;
errorMessage = '';
pass1 = '';
pass2 = '';
userName: string;
emailAddress: string;
user: User;
#ViewChild('f') signupForm: NgForm;
constructor(
private userDataService: UserDataService,
private router: Router) { }
ngOnInit() {
}
onSignup(form: NgForm) {
if (this.signupForm.valid === false) {
this.invalidRegister = true;
this.errorMessage = 'You must fill in all the fields!';
} else if (this.pass1 !== this.pass2) {
this.invalidRegister = true;
this.errorMessage = 'The passwords do not match!';
} else {
this.user = new User(this.userName, this.emailAddress, this.pass1);
console.log(this.user);
this.userDataService.addUser(this.user).subscribe(
data => {
console.log(data);
},
error => {
if (error.error.email === "duplicated") {
this.invalidRegister = true;
this.errorMessage = 'The email address you have used is already registered!';
} else if (error.error.username === "duplicated") {
this.invalidRegister = true;
this.errorMessage = 'The username is not available!';
}
},
() => {
this.invalidRegister = false;
this.router.navigate(['login']);
})
}
}
}
Register html
<h1>Register</h1>
<div class="alert alert-warning" *ngIf="invalidRegister">{{ errorMessage }}</div>
<form (ngSubmit)="onSignup()" #f="ngForm">
<div class="form-group row">
<label for="username" class="col-2 col-form-label">Username</label>
<div class="col-6">
<input
type="text"
id="username"
name="username"
ngModel
class="form-control"
required
#username="ngModel"
[(ngModel)]="userName">
<span
class="help-block text-danger"
*ngIf="!username.valid && username.touched">The username field is required!</span>
</div>
</div>
<div class="form-group row">
<label for="email" class="col-2 col-form-label">Email</label>
<div class="col-6">
<input
type="email"
id="email"
name="email"
ngModel
class="form-control"
required
email
#email="ngModel"
[(ngModel)]="emailAddress">
<span
class="help-block text-danger"
*ngIf="!email.valid && email.touched">Please enter a valid email!</span>
</div>
</div>
<div class="form-group row">
<label for="password" class="col-2 col-form-label">Password</label>
<div class="col-6">
<input
type="password"
id="password"
name="password"
ngModel
class="form-control"
required
#password="ngModel"
[(ngModel)]="pass1">
<span
class="help-block text-danger"
*ngIf="!password.valid && password.touched">The password field is required!</span>
</div>
</div>
<div class="form-group row">
<label for="pass" class="col-2 col-form-label">Confirm Password</label>
<div class="col-6">
<input
type="password"
id="pass"
name="pass"
ngModel
class="form-control"
required
#pass="ngModel"
[(ngModel)]="pass2">
<span
class="help-block text-danger"
*ngIf="!pass.valid && pass.touched">Please confirm your password!</span>
</div>
</div>
<button class="btn btn-primary" type="submit">Sign Up</button>
</form>
Login ts
import { Component, OnInit } from '#angular/core';
import { Router } from '#angular/router';
import { BasicAuthenticationService } from '../service/basic-authentication.service';
#Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
username = '';
password = '';
errorMessage = 'Invalid Credentials';
invalidLogin = false;
constructor(
private router: Router,
private basicAuthenticationService: BasicAuthenticationService) { }
ngOnInit() {
}
handleBasicAuthLogin() {
this.basicAuthenticationService.executeAuthenticationService(this.username, this.password)
.subscribe(
data => {
console.log(data);
this.router.navigate(['welcome', this.username]);
this.invalidLogin = false;
},
error => {
console.log(error);
this.invalidLogin = true;
}
);
}
Login html
<h1>Login</h1>
<div class="container">
<div class="alert alert-warning" *ngIf='invalidLogin'>{{ errorMessage }}</div>
<div>
User Name: <input type="text" name="username" [(ngModel)]="username" >
Password: <input type="password" name="password" [(ngModel)]="password">
<button (click)="handleBasicAuthLogin()" class="btn btn-success">Login</button>
</div>
</div>
When the registration is successful, you can add query params to the route and navigate to login
this.router.navigate(['login'], {queryParams: { registered: 'true' } });
Url will look like this: https://foobar.com/login?registered=true
In login.ts
infoMessage = '';
ngOnInit() {
this.route.queryParams
.subscribe(params => {
if(params.registered !== undefined && params.registered === 'true') {
infoMessage = 'Registration Successful! Please Login!';
}
});
}
And add this kind of line in login.html
<span *ngIf="infoMessage.length > 0">{{ infoMessage }}</span>