am sending an put request based on these files.
Venue.ts file
export class Venue {
id: number;
venueName: string;
cityName: string;
emailContact: string;
fighter1: string;
fighter2: string;
dateOfFight: Date;
active: boolean;
}
My Angular Component files:
create-venue.component.html
<h3>Create Event</h3>
<div [hidden]="submitted" style="width: 400px;">
<form (ngSubmit)="onSubmit()">
<div class="form-group">
<label for="name">Venue Name</label>
<input type="text" class="form-control" id="venueName" required [(ngModel)]="venue.venueName" name="venueName">
</div>
<div class="form-group">
<label for="name">City Name</label>
<input type="text" class="form-control" id="cityName" required [(ngModel)]="venue.cityName" name="cityName">
</div>
<div class="form-group">
<label for="name">Email Contact</label>
<input type="text" class="form-control" id="emailContact" required [(ngModel)]="venue.emailContact" name="emailContact">
</div>
<div class="form-group">
<label for="name">Fighter 1 Contact</label>
<input type="text" class="form-control" id="fighter1" required [(ngModel)]="venue.fighter1" name="fighter1">
</div>
<div class="form-group">
<label for="name">Fighter 2 Contact</label>
<input type="text" class="form-control" id="fighter2" required [(ngModel)]="venue.fighter2" name="fighter2">
</div>
<div class="form-group">
<label for="name">Choose a time for your Event:</label>
<input type="datetime-local" class="form-control" id="dateOfFight" min="2021-01-01T00:00" max="2023-06-14T00:00" required [(ngModel)]="venue.dateOfFight" name="dateOfFight">
</div>
<button type="submit" class="btn btn-success">Submit</button>
</form>
</div>
<div [hidden]="!submitted">
<h4>You submitted successfully!</h4>
<!-- <button class="btn btn-success" (click)="newVenue()">Add</button> -->
</div>
create-venue.component.ts
import { VenueService } from '../venue.service';
import { Venue} from '../venue';
import { Component, OnInit } from '#angular/core';
import { Router } from '#angular/router';
#Component({
selector: 'app-create-venue',
templateUrl: './create-venue.component.html',
styleUrls: ['./create-venue.component.css']
})
export class CreateVenueComponent implements OnInit {
venue: Venue = new Venue();
submitted = false;
constructor(private venueService: VenueService,
private router: Router) {}
ngOnInit() {
}
newVenue(): void {
this.submitted = false;
this.venue = new Venue();
}
save() {
this.venueService.createVenue(this.venue)
.subscribe(data => console.log(data), error => console.log(error));
this.venue = new Venue();
this.gotoList();
}
onSubmit() {
this.submitted = true;
this.save();
}
gotoList() {
this.router.navigate(['/venues']);
}
}
My current sent data in chrome:
I am quite new to javascript and angular, maybe this was answered before but I have no idea how to get the input data into the Venue object...
Edit:
This is my header tab:
I
using a string instead of Date type for the dateOfFight property will let you post to the backend without issue.
You can then generate the date with new Date(datestring) on your server if needed. On the front end you can look into date pipes which will help you format the string accordingly.
You also seem to not be capturing any values in your date input. Notice venue.dateOfFight is not even there. Perhaps try logging out your data before posting
You can use a string instead of date type dateOfFight: string;, and before saving, trasform it into a date format with Moment js.
moment(Date.now()).format('YYYY-MM-DD').toString()
Related
I have this inscription form. I tried to validate it but in vain. inputs are saved in my database despite they are empty I want to have these validations:
All inputs are required
email address should be valid
name should be composer by only letters
Password should have minimum 8 characters, at least 1 uppercase
letter, 1 lowercase letter and 1 number
I want to have a message under evey invalid input.(in <div id="na"></div> for example).How can I do this please?
HTML file
<h2 class="text-center">Inscription</h2>
<div class="row">
<div class="col-md-3">
</div>
<div class="col-md-6 col-md-offset-3">
<div class="jumbotron">
<form [formGroup]="angForm" (ngSubmit)="postdata(angForm)" autocomplete="off">
<div class="form-group mb-3">
<label for="name">Nom</label>
<input type="text" name="name" formControlName="name" autocomplete="off" id="name"
class="form-control input-sm" placeholder="Nom">
</div>
<div id="na"></div>
<div class="form-group mb-3">
<label for="email">Email</label>
<input type="email" name="email" formControlName="email" autocomplete="off" id="email"
class="form-control input-sm" placeholder="Email">
</div>
<div id="mail"></div>
<div class="form-group mb-3">
<label for="Password">Mot de passe</label>
<input type="password" name="Password" formControlName="password" autocomplete="off"
id="password" class="form-control input-sm" placeholder="Mot de passe">
</div>
<div id="pwd"></div>
<button type="sumit" class="btn btn-success">Enregistrer</button>
</form>
</div>
</div>
<div class="col-md-3">
</div>
</div>
Type script file
import { Component, OnInit } from '#angular/core';
import { FormGroup, FormControl, FormBuilder, Validators, NgForm } from '#angular/forms';
import { first } from 'rxjs/operators';
import { Router } from '#angular/router';
import { ApiService } from '../api.service';
#Component({
selector: 'app-inscription',
templateUrl: './inscription.component.html',
styleUrls: ['./inscription.component.css']
})
export class InscriptionComponent implements OnInit {
angForm: FormGroup;
constructor(private fb: FormBuilder,private dataService: ApiService,private router:Router) {
this.angForm = this.fb.group({
email: [],
password: [],
name: [],
mobile: []
});
}
ngOnInit() {
}
postdata(angForm1:any){this.dataService.userregistration(angForm1.value.name,angForm1.value.email,angForm1.value.password)
.pipe(first())
.subscribe(
data => {
this.router.navigate(['login']);
},
error => {
});
}
get email() { return this.angForm.get('email'); }
get password() { return this.angForm.get('password'); }
get name() { return this.angForm.get('name'); }
}
thanks in advance
this.angForm = this.fb.group({
email: ['', Validators.required, Validators.email],
password: ['', Validators.required, Validators.minLength(8), Validators.pattern("(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}")],
name: ['', Validators.required, Validators.pattern('^[a-zA-Z ]*$')],
mobile: [null, Validators.required, Validators.minLength(10), Validators.maxLength(10)]
});
This is the syntax for Validations.
In HTML, before closing of form-group div write
<span class="text-danger"
*ngIf="(angForm.name.touched || submitted) &&
angForm.name.errors?.required">
Name is required
</span>
<span class="text-danger"
*ngIf="((angForm.password.touched || submitted) &&
angForm.password.errors?.required )|| (angForm.invalid && submitted)">
Must contain at least one number and one uppercase and lowercase letter, and at least 8 or more characters </span>
same applies for email, mobile error msg in HTML.
Please refer for reactive form validation.
https://www.freecodecamp.org/news/how-to-validate-angular-reactive-forms/
response to Rothitha
If you don't want to use the "auxiliar variable" submitted you can use in submit.
submit(form:FormGroup)
{
if (form.invalid)
form.markallAsTouched()
else
{
..doSomething..
}
}
If we can better mannagement about errors (remove this ugly *ngIf="angForm.get('password').touched && angForm.get('password').touched" we can use a tecnica similar bootstrap mannage the error
We use a .css like
.invalid-feedback
{
display:none
}
.ng-invalid.ng-touched ~ .invalid-feedback
{
display: block;
}
And an html like
<!--enclosed all under a div-->
<div>
<!--a label-->
<label for="email">Email</label>
<!--a input-->
<input id="email" formControlName="email">
<!--a div class="invalid-feedback-->
<div class="invalid-feedback">
<!--if there're several validators use *ngIf-->
<div *ngIf="angForm.controls.email.errors?.required">Email is required</div>
<div *ngIf="angForm.controls.email.errors?.email">it's not a valid email</div>
</div>
</div>
See stackblitz
I need to add a new product to my table. This is working http://localhost:8080/product/create/ on Postman. When I post and add a new product it returns the id and automatically adds it to my table. My problem is how can I achieve it on angular CLI. I don't how will I do it. Can somebody help me? Here's my code:
ProductsController.java
#PostMapping("/product/create/")
private int saveProduct(#RequestBody Products products)
{
productsService.save(products);
return products.getId();
}
app.component.ts
ngOnInit() {
this.getProduct();
}
public getProduct(): void {
this.productServive.getProduct().subscribe(
(response: Product[]) => {
this.products = response;
},
(error: HttpErrorResponse)=> {
alert(error.message);
}
)
}
public onAddProduct(addForm: NgForm): void {
this.productServive.addProduct(addForm.value).subscribe(
(response: Product) => {
console.log(response);
this.getProduct();
},
(error: HttpErrorResponse) => {
alert(error.message);
}
);
}
product.service.ts
private apiServerUrl = environment.apiBaseUrl;
constructor(private http: HttpClient) { }
public getProduct() : Observable<Product[]> {
return this.http.get<Product[]>(`${this.apiServerUrl}/products/hasstocks`);
}
public addProduct(product: Product) : Observable<Product> {
return this.http.post<Product>(`${this.apiServerUrl}/product/create/`, product);
}
app.component.html
<form #addForm="ngForm" (ngSubmit)="onAddProduct(addForm)">
<div class="mb-3">
<label for="name" class="col-form-label">Name:</label>
<input type="text" class="form-control" id="name" ngForm name="name">
</div>
<div class="mb-3">
<label for="description" class="col-form-label">Description:</label>
<input type="text" class="form-control" id="description" ngModel name="description">
</div>
<div class="mb-3">
<label for="sku" class="col-form-label">SKU:</label>
<input type="text" class="form-control" id="sku" ngModel name="sku">
</div>
<div class="mb-3">
<label for="price" class="col-form-label">Price:</label>
<input type="text" class="form-control" id="price" ngModel name="price">
</div>
<div class="mb-3">
<label for="quantity" class="col-form-label">Quantity:</label>
<input type="text" class="form-control" id="quantity" ngModel name="quantity">
</div>
<div class="float-end">
<button [disabled]="addForm.invalid" type="button" class="btn btn-primary">Add Product</button>
</div>
</form>
It can not be together, you must separete 2 methods as save and getProduct but you can attach getProduct methods and page and when you save products and refresh the page it will seems automatically adds it to your table
While i'm trying to send those values into the Firebase i'm getting this error: "Invalid document reference. Document references must have an even number of segments, but printers has 1"
ill post pictures of the code below maybe someone can shed some light on this thanks a lot!
Typescript:
import { Component, OnInit } from '#angular/core';
import { PrintersService } from '../printers.service';
#Component({
selector: 'app-addprinter',
templateUrl: './addprinter.component.html',
styleUrls: ['./addprinter.component.css']
})
export class AddprinterComponent implements OnInit {
constructor(private printersService: PrintersService) { }
ngOnInit() {
}
AddPrinter(form) {
this.printersService.AddPrinter(
form.value.hostName,
form.value.ip,
form.value.location,
form.value.manufacturer,
form.value.model,
form.value.specificLocation).then(
data => console.log(data))
.catch(err => console.log(err));
console.log(form);
}
}
Service:
import { Injectable } from '#angular/core';
import { AngularFirestore } from '#angular/fire/firestore';
#Injectable({
providedIn: 'root'
})
export class PrintersService {
constructor(private fs: AngularFirestore) { }
getAllPrinters() {
return this.fs.collection('Printers').valueChanges();
}
AddPrinter(HostName, Ip, Location, Manufacturer, Model, SpecificLocation) {
return this.fs.doc('Printers/').set({
HostName,
Ip,
Location,
Manufacturer,
Model,
SpecificLocation
});
}
}
HTML:
<br><br><br><br>
<h2 class="text-center">Add Printer</h2>
<form #f="ngForm" (ngSubmit)="AddPrinter(f)">
<input ngModel name="hostName" #hostname="ngModel" type="text" class="formControl" required placeholder="Enter HostName here">
<div class="alert alert-danger" *ngIf="hostname.touched &&hostname.errors?.required">The HostName is requied</div>
<input ngModel name="ip" #ip="ngModel" type="text" class="formControl" required placeholder="Enter Ip here">
<div class="alert alert-danger" *ngIf="ip.touched &&ip.errors?.required">The Ip is requied</div>
<input ngModel name="location" #location="ngModel" type="text" class="formControl" required placeholder="Enter Loctaion here">
<div class="alert alert-danger" *ngIf="location.touched &&location.errors?.required">The Location is requied</div>
<input ngModel name="manufacturer" #manufacturer="ngModel" type="text" class="formControl" required placeholder="Enter Manufacturer here">
<div class="alert alert-danger" *ngIf="manufacturer.touched &&manufacturer.errors?.required">The Manufacturer is requied</div>
<input ngModel name="Model" #model="ngModel" type="text" class="formControl" required required placeholder="Enter Model here">
<div class="alert alert-danger" *ngIf="model.touched &&model.errors?.required">The Model is requied</div>
<input ngModel name="specificLocation" #specificLocation="ngModel" type="text" class="formControl" required placeholder="Enter Specific Location here">
<div class="alert alert-danger" *ngIf="specificLocation.touched && specificLocation.errors?.required">The Specific Location is requied</div>
<button class="btn btn-primary" [disabled]="f.invalid">Send</button>
</form>
The error is complaining about this line:
this.fs.doc('Printers/').set({ ... })
If you want to create a document with set(), you must provide the full path including the collection where it lives, for example "Printers/printer_id".
If you are trying to add a new document with a random ID, use add() instead of set().
this.fs.collection('Printers').add({ ... })
I'm try to make custom Validators that give user message when he/she leave a space on text but i received this error.
1-Cannot read property 'removeSpaceFromUserName' of undefined
2-Cannot read property 'required' of null
at Object.eval [as updateDirectives]
Here's the html of the component
<form [formGroup]='form'>
<div class="form-group">
<label for="username">Username</label>
<input
formControlName='username'
id="username"
type="text"
class="form-control">
<div *ngIf="username.touched && username.touched" class="alert alert-danger">
<div *ngIf="username.errors.required"> You need to enter user name</div>
<div *ngIf="username.errors.minlength"> Min Length is
{{ username.errors.minLength.requiredLength}}
</div>
<div *ngIf="UserNameValiditors.removeSpaceFromUserName">
removeSpaceFromUserName </div>
</div>
</div>
<div class="form-group">
<label for="password">Password</label>
<input
formControlName='password'
id="password"
type="text"
class="form-control">
</div>
<button class="btn btn-primary" type="submit">Sign Up</button>
</form>
Here's the custom validator class
import { AbstractControl, ValidationErrors } from "#angular/forms";
export class UserNameValiditors {
static removeSpaceFromUserName(control: AbstractControl): ValidationErrors | null {
if ((control.value as string).indexOf(' ') >= 0) {
return {
removeSpaceFromUserName: true
};
}
else {
return null;
}
}
}
import { Component } from '#angular/core';
import { FormControl , FormGroup , Validators } from "#angular/forms";
import { UserNameValiditors } from './UserNameValditors';
#Component({
selector: 'signup-form',
templateUrl: './signup-form.component.html',
styleUrls: ['./signup-form.component.css']
})
export class SignupFormComponent {
form= new FormGroup(
{
username : new FormControl('',
[
Validators.required,
Validators.minLength(3) ,
UserNameValiditors.removeSpaceFromUserName
]) ,
password : new FormControl('',Validators.required)
});
get username()
{
return this.form.get('username');
}
}
You can try with this solution.
I have create a demo on Stackblitz
app.component.ts
myForms: FormGroup;
constructor(fb: FormBuilder) {
this.myForms = fb.group({
username: [null, Validators.compose([
Validators.required, Validators.minLength(3), usernameValidator])],
password: [null, [
Validators.required]]
});
}
app.component.html
<form [formGroup]="myForms">
<label>User Name :
<input type="text" formControlName="username">
</label><br>
<div class="errors" *ngIf="myForms.get('username').invalid && (myForms.get('username').touched || myForms.get('username').dirty)">
<div *ngIf="myForms.get('username').hasError('required')">
username is required
</div>
<div *ngIf="myForms.get('username').errors.minlength">
username must be at least 3 characters
</div>
<div class="error-text" *ngIf="myForms.get('username').hasError('removeSpaceFromUserName')">
removeSpaceFromUserName
</div>
</div>
<div class="form-group">
<label for="password">Password</label>
<input
formControlName='password'
id="password"
type="text"
class="form-control">
</div>
<button class="btn btn-primary" type="submit">Sign Up</button>
</form>
Use hasError() to check if certain error is present on the form.
html code
<div *ngIf="username.hasError('required')"> You need to enter user name</div>
<div *ngIf="username.hasError('minlength')"> Min Length is {{ username.hasError('minLength')}}
</div>f
<div *ngIf="username.hasError('removeSpaceFromUserName')">
removeSpaceFromUserName </div>
</div>
Your working code is here
I've been battling with these block of codes for some days, and even when i try initializing it as an object i get errors.
this is my restaurantForm.ts file
import { Component, OnInit } from '#angular/core';
import {RestaurantService} from '../../restaurant.service';
import {ProductService} from '../../product.service';
import {ActivatedRoute, Router} from '#angular/router';
import 'rxjs/add/operator/take';
import {Product} from '../../model/product';
#Component({
selector: 'app-product-form',
templateUrl: './restaurant-form.component.html',
styleUrls: ['./restaurant-form.component.css']
})
export class RestaurantFormComponent implements OnInit {
restaurants$;
id;
product: Product;
constructor(private restaurantService: RestaurantService,
private productService: ProductService,
private route: ActivatedRoute,
private router: Router) {
this.restaurants$ = this.restaurantService.getAll();
this.id = this.route.snapshot.paramMap.get('id');
if (this.id) {
this.productService.get(this.id).take(1).subscribe(p => this.product = p);
}
this.product = new Product();
}
save(product) {
if (this.id) {
this.productService.update(this.id, product);
} else {
this.productService.create(product);
}
this.router.navigate(['/admin/restaurants']);
}
delete() {
if (!confirm('Are you sure you want to delete this product?')) { return ; }
this.productService.delete(this.id);
this.router.navigate(['/admin/restaurants']);
}
ngOnInit() {
}
}
this is my product model
export interface Product {
$key: string;
title: string;
price: number;
restaurant: string;
imageUrl: string;
}
My restaurantForm.html
<div class="container">
<div class="row">
<div class="col-md-6">
<form #f="ngForm" (ngSubmit)="save(f)">
<div class="form-group">
<label for="title">Title</label>
<input #title="ngModel" [(ngModel)]="product.title" name="title" id="title" type="text" class="form-control" required>
<div class="alert-danger alert" *ngIf="title.touched && title.invalid">
Title is required.
</div>
</div>
<div class="form-group">
<label for="price">Delivery Price</label>
<div class="input-group">
<span class="input-group-addon">₦</span>
<input #price="ngModel" [(ngModel)]="product.price" name="price" id="price"
type="number" class="form-control" required [min]="0">
</div>
<div class="alert alert-danger" *ngIf="price.touched && price.invalid">
<div *ngIf="price.errors.required">
Delivery Price is required
</div>
<div *ngIf="price.errors.min">
Delivery Price should be 0 or higher.
</div>
</div>
</div>
<div class="form-group">
<label for="restaurant">Restaurant</label>
<select #restaurant="ngModel" [(ngModel)]="product.restaurant" name="restaurant" id="restaurant" class="form-control" required>
<option value=""></option>
<option *ngFor="let r of restaurants$ | async" [value]="r.$key">
{{ r.name }}
</option>
</select>
<div class="alert alert-danger" *ngIf="restaurant.touched && restaurant.invalid">
Please select a restaurant.
</div>
</div>
<div class="form-group">
<label for="imageUrl">Image Url</label>
<input #imageUrl="ngModel" [(ngModel)]="product.imageUrl" name="imageUrl"
id="imageUrl" type="text" class="form-control" required url>
<div class="alert alert-danger" *ngIf="imageUrl.touched && imageUrl.invalid">
<div *ngIf="imageUrl.errors.required">Image Url is required.</div>
<div *ngIf="imageUrl.errors.url">Please enter a valid Url.</div>
</div>
</div>
<button class="btn btn-primary">Save</button>
<button type="button" (click)="delete()" class="btn btn-danger">Delete</button>
</form>
</div>
<div class="col-md-6">
<app-product-card [product]="product" [showActions]="false"></app-product-card>
</div>
</div>
</div>
I get the same errors with price, $key, restaurant and imageUrl.
thanks in advance. Although Ive looked up some solutions saying i should use elvis Operator e.g 'product?.title' this method isnt still working.
Because product is undefined, you need to declare and initialize it with empty object inside the constructor or ngOninit.
EDIT:
You need to have the Product declared in the component as,
const product : Produce = { $key: "", title: "",price:0,restuarant :"" ,imageurl:"" };
When the template get initialized, the product is undefined and it continues until the response return from API. Add a check for the template where you bind the object properties.Do the same for price etc.
<input *ngIf="product.title" #title="ngModel" [(ngModel)]="product.title" name="title" id="title" type="text" class="form-control" required>