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({ ... })
Related
I have a problem trying to dynamically grab the text and send it to my e-mail. It works when manually typing into TS onSendEmail. I am using free email hosting server and the assets folder has required files needed
HTML code
<form (ngSubmit)="onSendEmail(addEmailForm)" #addEmailForm ="ngForm">
<fieldset>
<legend>Contact us</legend>
<label>Your name</label> <br>
<input ngModel name="name" type="text" placeholder="Your name" size="20" required ><br>
<label>E-mail address</label> <br>
<input ngModel name="email" type="text" placeholder="example#example.com" size="20" required><br>
<label>Subject</label> <br>
<input ngModel name="subject" type="text" size="20"><br>
<label>Body</label> <br>
<textarea ngModel name="body" type="text" cols="40" rows="6" required></textarea><br>
<button [disabled]="addEmailForm.invalid" >Send</button>
</fieldset>
</form>
Typescript code
import { HttpClient } from '#angular/common/http';
import { Component, OnInit, AfterViewInit } from '#angular/core';
import { NgForm } from '#angular/forms';
declare let Email: any;
import 'src/assets/smtp.js'; // available in assets folder
#Component({
selector: 'app-map',
templateUrl: './shops.component.html',
styleUrls: ['./shops.component.css']
})
export class ShopsComponent implements OnInit, AfterViewInit {
constructor(private http: HttpClient) { }
ngOnInit(): void { }
body: any
subject: any;
email: any;
name: any;
onSendEmail(addEmailForm: NgForm) {
Email.send({
Host : "smtp.elasticemail.com",
Username : "myemail#hotmail.com",
Password : "mypassword",
To : 'mysecondemail#hotmail.com',
Name: this.name,
From : this.email, // when I write these manually the email gets sent
Subject : this.subject,
Body : this.body,
}).then(
(message: any) => alert("E-mail sent, thank you.")
);
}
}
To get filled data from your from You should use:
onSendEmail(addEmailForm: NgForm) {
let data = addEmailForm.value;
//...
}
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()
I'm trying a user registration form using MEAN, but I keep getting error 500 on passing data to the database.
I tried using save instead of the register, but that doesn't hash the password.
I had this method working on a project without angular, but it's not working here.
If there is an alternative to save the data with a hashed password, that's also helpful.
This is the post code:
app.post('/signup', VerifyToken, (req,res) =>
{
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS");
console.log(req.body);
const errors = validationResult(req);
if (!errors.isEmpty())
{
return res.status(422).jsonp(errors.array());
}
else
{
User = new userData(
{
name: req.body.user.name,
email: req.body.user.email,
blood: req.body.user.blood,
address1: req.body.user.address1,
address2: req.body.user.address2,
});
userData.register(User, req.body.user.password);
}
});
This is the service that sends data:
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
#Injectable({
providedIn: 'root'
})
export class UsersService {
constructor(private http:HttpClient) { }
// getUsers()
// {
// return this.http.get('');
// }
newUser(user)
{
return this.http.post('http://localhost:5000/signup',{'user' : user})
.subscribe(data => {console.log(data)});
}
};
And this is the signup component TS code:
import { Component, OnInit } from '#angular/core';
import { Router } from '#angular/router';
import { UserModel } from './user.model';
import { UsersService } from '../users.service';
#Component({
selector: 'app-signup',
templateUrl: './signup.component.html',
styleUrls: ['./signup.component.css']
})
export class SignupComponent implements OnInit {
constructor(private usersService: UsersService, private router: Router) { }
title: String = "Register as a new Donor here";
userItem = new UserModel(null,null,null,null,null,null);
ngOnInit(): void {
}
AddUser()
{
this.usersService.newUser(this.userItem);
console.log("called");
alert("success");
this.router.navigate(['/']);
}
}
This is the HTML code of the signup component:
<div>
<h4 class="card-header">{{title}}</h4>
</div>
<div class="container formDiv">
<form (ngSubmit)="AddUser()">
<div class="form-group">
<input type="text" class="form-control" id="fullName" name="name" [(ngModel)]="userItem.name" placeholder="Enter Full Name" required>
</div>
<div class="form-group">
<input type="email" class="form-control" id="email" name="email" [(ngModel)]="userItem.email" placeholder="Enter Email address" required>
</div>
<div class="form-group">
<select class="form-control" name="blood" id="bloodType" [(ngModel)]="userItem.blood" required>
<option value="0">Select Blood Type</option>
<option value="A+">A+</option>
<option value="A-">A-</option>
<option value="B+">B+</option>
<option value="B-">B-</option>
<option value="O+">O+</option>
<option value="O-">O-</option>
<option value="AB+">AB+</option>
<option value="AB-">AB-</option>
<option value="Bombay">Bombay Blood group</option>
</select>
</div>
<div class="form-group">
<input type="text" class="form-control" id="addressL1" name="address1" [(ngModel)]="userItem.address1" placeholder="Enter Address Line 1" required>
</div>
<div class="form-group">
<input type="text" class="form-control" id="addressL2" name="address2" [(ngModel)]="userItem.address2" placeholder="Enter Address Line 2" required>
</div>
<div class="form-group">
<input type="password" class="form-control" id="password" name="password" [(ngModel)]="userItem.password" placeholder="Enter Password" required>
</div>
<div class="form-group">
<input type="password" class="form-control" id="confPassword" name="confPassword" placeholder="Confirm Password" required>
</div>
<button type="submit" value="submit" class="btn btn-primary">Register</button>
</form>
</div>
I have written a registration page component in Angular. I have followed what few tutorials there are and I have stumbled upon a very frustrating bug. Pressing the submit button on the form will simply cause the console to print out "undefined" when trying to access the NgForm's value. Accessing the "valid" field of the NgForm will return true or false, as expected.
the page:
<app-players></app-players>
<div class="container" style="text-align:center">
<h3>Register a new account!</h3>
<form #f="ngForm" (ngSubmit)="onSubmit(f)">
<label>Username:</label> <input type="text" id="username"
required #username="ngModel"
name="username" ngModel><br>
<label>Password:</label> <input type="password" id="password"
required #password="ngModel"
name="password" ngModel><br>
<label>Email:</label> <input type="text" id="email"
required #email="ngModel"
name="email" ngModel><br>
<button type="submit" class="btn btn-success" [disabled]="!newPlayerEntry.form.valid">Submit</button>
</form>
</div>
<div id = "result">
</div>
The component:
import { Component, OnInit } from '#angular/core';
import { NgForm } from '#angular/forms';
import { NewPlayer } from './new-player';
#Component({
selector: 'app-players-register',
templateUrl: './players-register.component.html',
styleUrls: ['./players-register.component.css']
})
export class PlayersRegisterComponent implements OnInit {
constructor() {
}
ngOnInit() {
}
onSubmit(f: NgForm) {
console.log(f.value);
}
}
You need remove [disabled]="!newPlayerEntry.form.valid" and change to [disabled]="!f.valid"
This is working version
https://stackblitz.com/edit/angular-mgmmsq?file=src%2Fapp%2Fapp.component.html
If I tab through the text inputs without entering anything, the error msg divs display indicating that the required validator has fired correctly. However, if I type anything into one of the fields, the console immediately throws this error:
Cannot read property 'required' of null
Here is my component:
import { PasswordValidators } from './../validators/password.validators';
import { Component, OnInit } from '#angular/core';
import { FormBuilder, Validators, FormGroup, FormControl } from '#angular/forms';
#Component({
selector: 'app-changepassword-form',
templateUrl: './changepassword-form.component.html',
styleUrls: ['./changepassword-form.component.css']
})
export class ChangepasswordFormComponent {
form;
constructor(fb: FormBuilder) {
this.form = fb.group({
newPassword: ['', Validators.required],
confirmPassword: ['', Validators.required]
})
}
get newPassword() {
return this.form.get('newPassword');
}
get confirmPassword() {
return this.form.get('confirmPassword');
}
}
and HTML:
<form [formGroup]="form">
<div class="form-group">
<label for="newPassword">New Password</label>
<input formControlName="newPassword" id="newPassword" type="text" class="form-control">
<div class="alert alert-danger" *ngIf="newPassword.touched && newPassword.errors.required">
Required
</div>
</div>
<div class="form-group">
<label for="confirmPassword">Confirm Password</label>
<input formControlName="confirmPassword" id="confirmPassword" type="text" class="form-control">
<div class="alert alert-danger" *ngIf="confirmPassword.touched && confirmPassword.errors.required">
Required
</div>
</div>
<p><button class="btn btn-primary">Submit</button></p>
</form>
That error is coming from this:
*ngIf="newPassword.touched && newPassword.errors.required"
When you put in a value, there is no longer an errors collection so checking newPassword.errors.required generates that Cannot read property 'required' of null error.
Try something like this instead:
*ngIf="newPassword.touched && newPassword.errors?.required"
As an example, mine looks like this:
<div class="col-md-8">
<input class="form-control"
id="productNameId"
type="text"
placeholder="Name (required)"
required
minlength="3"
[(ngModel)] = product.productName
name="productName"
#productNameVar="ngModel" />
<span class="help-block" *ngIf="(productNameVar.touched ||
productNameVar.dirty || product.id !== 0) &&
productNameVar.errors">
<span *ngIf="productNameVar.errors.required">
Product name is required.
</span>
<span *ngIf="productNameVar.errors.minlength">
Product name must be at least three characters.
</span>
</span>
</div>
You can also use the following syntax and it will work without the need to have a value first:
form.get('newPassword').hasError('required')
This will check for 'required' in the errors.
This will work as well and it's more concise :
form.hasError('required','newPassword')
If you are compiling with AOT option, according to this article, you should privilege hasError() syntax:
Don’t use control.errors?.someError, use control.hasError(‘someError’)