Angular 11 Forms and Http POST - html

I'm trying to post information I entered from my text boxes but I'm receiving an error,
core.js:6210 ERROR TypeError: Cannot read property 'toString' of undefined
I was wondering as to why my variables are appearing as undefined? Additionally, how might I fix this problem?
Component File
import { Component, Inject, OnInit } from '#angular/core';
import { HttpClient, HttpParams } from '#angular/common/http';
import { FormGroup, FormControl, FormBuilder } from '#angular/forms';
#Component({
selector: 'app-WeatherData',
templateUrl: './AddWeatherData.component.html',
})
export class PostDataComponent {
baseUrl: string;
date: number;
temperatureC: number;
summary: string;
weatherForm: FormGroup;
constructor(public http: HttpClient, #Inject('BASE_URL') baseUrl: string, private formBuilder: FormBuilder) {
this.baseUrl = "https://localhost:44347/WeatherForecast";
this.weatherForm = formBuilder.group({
Date: new FormControl(),
TemperatureC: new FormControl(),
Summary: new FormControl()
});
}
CreateData() {
const params = new HttpParams({
fromObject: {
'date': this.weatherForm.value.date.toString(),
'temperatureC': this.weatherForm.value.temperatureC.toString(),
'summary': this.weatherForm.value.summary.toString()
}
});
let endPoints = '';
console.log(params);
this.http.post(this.baseUrl + endPoints, {},{ params: params }).subscribe(data => {
console.log(data);
});
}
}
My HTML file includes the forms setup and the type declarations are text for each of the variables I included. Is this an issue?
HTML File
<form [formGroup]="weatherForm">
<div class="form-group">
<label for="inputDate">Date</label>
<input type="text" class="form-control" id="inputDate" formControlName="Date">
</div>
<div class="form-group">
<label for="inputTemp">Temperature C</label>
<input type="text" class="form-control" id="inputTemp" formControlName="TemperatureC">
</div>
<div class="form-group">
<label for="inputSummary">Summary</label>
<input type="text" class="form-control" id="inputSummary" formControlName="Summary">
</div>
<button type="submit" class="btn btn-primary" (click)="CreateData()">Add New Weather Data</button>
</form>

debug at
fromObject: {
'date': this.weatherForm.value.date.toString(),
'temperatureC': this.weatherForm.value.temperatureC.toString(),
'summary': this.weatherForm.value.summary.toString()
}
and check the value of this.weatherForm.value
all properties are case sensitive TemperatureC is not equal to temperatureC
and if you execute undefine.toString() then you will get the error

Please replace your code with below,
import { Component, Inject, OnInit } from '#angular/core';
import { HttpClient, HttpParams } from '#angular/common/http';
import { FormGroup, FormControl, FormBuilder } from '#angular/forms';
#Component({
selector: 'app-WeatherData',
templateUrl: './AddWeatherData.component.html',
})
export class PostDataComponent {
baseUrl: string;
date: number;
temperatureC: number;
summary: string;
weatherForm: FormGroup;
constructor(public http: HttpClient, #Inject('BASE_URL') baseUrl: string, private formBuilder: FormBuilder) {
this.baseUrl = "https://localhost:44347/WeatherForecast";
this.weatherForm = formBuilder.group({
Date: new FormControl(),
TemperatureC: new FormControl(),
Summary: new FormControl()
});
}
CreateData() {
const params = new HttpParams({
fromObject: {
'date': this.weatherForm.value.Date.toString(),
'temperatureC': this.weatherForm.value.TemperatureC.toString(),
'summary': this.weatherForm.value.Summary.toString()
}
});
let endPoints = '';
console.log(params);
this.http.post(this.baseUrl + endPoints, {},{ params: params }).subscribe(data => {
console.log(data);
});
}
}

Related

get input values by there class

I have a following angular component ts with an ability to add dynamic fields to a form:
import {Component, ElementRef, OnInit, ViewChild} from '#angular/core';
import {Buildcompany} from "../../models/buildcompany.model";
import {BuildcompanyService} from "../../services/buildcompany.service";
import { FormGroup, FormControl, FormArray, FormBuilder } from '#angular/forms'
#Component({
selector: 'app-add-buildcompany',
templateUrl: './add-buildcompany.component.html',
styleUrls: ['./add-buildcompany.component.css'],
})
export class AddBuildcompanyComponent implements OnInit {
buildcompany: Buildcompany={
shortname:'',
fullname:'',
address:'',
telephone:'',
website:'',
sociallinks:'',
foundationyear:''
}
submitted=false;
#ViewChild('network', {static: true}) networkElement: ElementRef;
netw?: [];
constructor(private buildcompanyService:BuildcompanyService,networkElement: ElementRef) {
this.networkElement=networkElement;
}
ngOnInit(): void {
}
add(){
let row = document.createElement('div');
row.className = 'row';
row.innerHTML = `
<br>
<input type="text" id="netw" name="network[]" #network class="form-control netw">"`;
let row2 = document.createElement('div');
row2.innerHTML = `
<br>
<input type="text" name="links[]" class="form-control">"`;
// #ts-ignore
document.querySelector('.showInputField').appendChild(row);
// #ts-ignore
document.querySelector('.showInputField').appendChild(row2);
}
saveBuildcompany(): void {
// #ts-ignore
this.netw = (<HTMLInputElement>document.getElementsByClassName("netw")).value;
// #ts-ignore
console.log(this.netw[0].value);
const data = {
shortname: this.buildcompany.shortname,
fullname: this.buildcompany.fullname,
address: this.buildcompany.address,
telephone: this.buildcompany.telephone,
website: this.buildcompany.website,
sociallinks: this.buildcompany.sociallinks,
foundationyear: this.buildcompany.foundationyear
};
this.buildcompanyService.create(data)
.subscribe({
next: (res) => {
console.log(res);
this.submitted = true;
},
error: (e) => console.error(e)
});
}
newBuildcompany(): void {
this.submitted = false;
this.buildcompany = {
shortname: '',
fullname:'',
address:'',
telephone:'',
website:'',
foundationyear:''
};
}
}
Is that posible at all to get values of those dynamicly added fields into an array on save() function? I can see in a console that they are actually shown. The class is called netw. Or what is the best approche to this task?
UPDATE
I tryed to add a formgroup and got the following error
Error:
ngModel cannot be used to register form controls with a parent formGroup directive. Try using
formGroup's partner directive "formControlName" instead. Example:

How to set model data in Reactive Forms, Angular 9

I started to study angular, i created a single crud using Angular 9 and Spring boot, but i have a question, what I'm trying to do is to get the data of the table below and move it for a reactive form to upload the data.
How to solve the issue?
enter image description here
.
enter image description here
<form [formGroup]="form" (ngSubmit)="submit()">
<div class="form-group">
<label for="">Nome</label>
<input type="text" formControlName="nome" class="form-control">
</div>
<div class="form-group">
<label for="">email</label>
<input type="text" formControlName="email" class="form-control">
</div>
<div class="form-group">
<label for="">username</label>
<input type="text" formControlName="username" class="form-control">
</div>
<button class="btn btn-outline-primary"> Salvar</button>
<button [routerLink]="['/']" style="margin-left: 1%;" class="btn btn-outline-warning"> Voltar</button>
</form>
My app-routing.module.ts:
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { ShowContactComponent } from './Componets/contact/show-contact/show-contact.component'
import { CreateContactComponent } from './Componets/contact/create-contact/create-contact.component'
const routes: Routes = [
{path:'', component:ShowContactComponent},
{path:'create', component:CreateContactComponent},
{path:'create/:id', component:CreateContactComponent}
];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
import { Component, OnInit } from '#angular/core';
import { FormBuilder, FormGroup, Validators } from '#angular/forms';
import { Contact } from '../contact-model/Contact';
import { ContactService } from '../../contact.service';
import { Router, ActivatedRoute } from '#angular/router';
#Component({
selector: 'app-create-contact',
templateUrl: './create-contact.component.html',
styleUrls: ['./create-contact.component.css']
})
export class CreateContactComponent implements OnInit {
form:FormGroup;
contacts:Contact[] = []
contact:Contact
constructor(private service:ContactService, private router:Router, private fb:FormBuilder, private AR:ActivatedRoute) { }
ngOnInit() {
// this.paramService();
this.validateForms();
}
submit(){
const formValue = this.form.value;
const contact:Contact = new Contact(formValue.nome, formValue.email ,formValue.username );
this.service.create(contact).subscribe(response =>{
this.contacts.push(response);
this.router.navigate([''])
console.log(response);
})
}
paramService(){
const formValue = this.form.value;
const contact:Contact = new Contact(formValue.nome, formValue.email ,formValue.username );
console.log(contact);
this.service.readOne(this.contact.id).subscribe(response =>{
this.form.patchValue({
nome: contact.nome,
email: contact.email,
username: contact.username
});
});
}
validateForms(){
this.form = this.fb.group({
nome: ['', Validators.required],
email: ['', Validators.required],
username: ['', Validators.required]
})
}
}
You can do it in this way:
validateForms(data?: Contact){
this.form = this.fb.group({
nome: [data.name || '', Validators.required],
email: [data.email || '', Validators.required],
username: [data.username || '', Validators.required]
})
}
Now you should pass the data to show in your form:
ngOnInit() {
// const contact: Contact = ...
this.validateForms(contact);
}
Please change 'validateForms' name to 'initForm'.

Angular TypeError: Cannot read property '0' of undefined when using event.target.file[0]

I'm currently trying to take a file input from a user and store it to Firebase Storage using AngularFire. Since it's undefined, I'm convinced that whatever file they're looking at, it's NULL, but my UI clearly shows that I'm successfully inputting a file, but the error gets caught as soon as I select the file. Am I misunderstanding how the input sends information to my TypeScript file?
Here's my TS file:
import { AngularFirestore } from '#angular/fire/firestore';
import { Component, OnInit, Input, ChangeDetectorRef } from '#angular/core';
import { finalize, tap, map } from 'rxjs/operators';
import { FormBuilder, FormGroup, FormArray, Validators } from '#angular/forms';
import { SubmitPostService } from './submit-post.service';
import { Post } from '../post.model';
import { Observable } from 'rxjs';
#Component({
selector: 'app-post-creation',
templateUrl: './post-creation.component.html',
styleUrls: ['./post-creation.component.scss']
})
export class PostCreationComponent implements OnInit {
private uuidv4 = require('uuid/v4');
// Main task
task: AngularFireUploadTask;
// Progress Monitoring
percentage: Observable<number>;
// Download URL
downloadURL: Observable<string>;
myForm: FormGroup;
post: Post;
ref: AngularFireStorageReference;
files: Observable<any>;
constructor(
private formBuilder: FormBuilder,
private postService: SubmitPostService,
private storage: AngularFireStorage,
) { }
ngOnInit() {
this.myForm = this.formBuilder.group({
title: ['', [Validators.required]],
artists: ['', [Validators.required]],
description: '',
medium: ''
});
this.myForm.valueChanges.subscribe(console.log);
}
onSubmit() {
this.post = new Post(
this.uuidv4(),
this.myForm.get('artists').value,
this.myForm.get('title').value,
new Date(),
new Date(),
`images/${Date.now()}_${this.myForm.get('title').value}`,
this.myForm.get('description').value,
this.myForm.get('medium').value
);
this.postService.submitPost(this.post);
}
upload(event: any) {
console.log('Upload successful');
try {
const file = event.target.file[0];
// The storage path
const path = `images/${Date.now()}_${file.name}`;
// Reference to storage bucket
this.ref = this.storage.ref(path);
// Main Task
this.task = this.ref.put(file);
// Tracks progress
this.percentage = this.task.percentageChanges();
this.percentage = this.task.snapshotChanges()
.pipe(map(s => (s.bytesTransferred / s.totalBytes) * 100));
this.downloadURL = this.ref.getDownloadURL();
} catch (err) { console.log(err); }
}
}
Here's my HTML:
<div>
<div class="progress">
<progress max="100" [value]="(percentage | async)"></progress>
</div>
<h1>Post Creation</h1>
<form [formGroup]="myForm" (ngSubmit)="onSubmit()">
<mat-form-field>
<input matInput placeholder="Title" formControlName="title">
</mat-form-field>
<br>
<mat-form-field>
<input matInput placeholder="Artists" formControlName="artists">
</mat-form-field>
<br>
<mat-form-field>
<input matInput placeholder="Description" formControlName="description">
</mat-form-field>
<br>
<mat-form-field>
<input matInput placeholder="Medium" formControlName="medium">
</mat-form-field>
<br>
<input type="file" (change)="upload($event)" accept=".png,.jpg">
<br>
<br>
<button mat-raised-button [disabled]="myForm.invalid" color="primary">Submit Post</button>
</form>
</div>
</body>
I've successfully created the Post objects in the Firestore, so it's not an issue of my firebase configs aren't correctly initialize.
In your upload method, in the const file = event.target.file[0]; statement, the file property should be plural

How to print data for one MySqL record in Angular

I have a table flight in my MySqL database:
I want to show in my Spring Boot application data only for the first record with flight_id=1
Here is my json
myflights-list.component.html:
<h3>Ticket</h3>
<div *ngIf="flight">
<div>
<label>departureCity: </label> {{flight.departureCity}}
</div>
<div>
<label>destinationCity: </label> {{flight.destinationCity}}
</div>
<div>
<label>price: </label> {{flight.price}}
</div>
<div>
<label>flightDuration: </label> {{flight.flightDuration}}
</div>
<div>
<label>transferNumber: </label> {{flight.transferNumber}}
</div>
<div>
<label>departureDate: </label> {{flight.departureDate}}
</div>
<div>
<label>departureTime: </label> {{flight.departureTime}}
</div>
<hr/>
</div>
myflights-list.component.ts
#Component({
selector: 'myflights-list',
templateUrl: './myflights-list.component.html',
styleUrls: ['./myflights-list.component.css']
})
export class MyflightsListComponent implements OnInit {
flight: Flight = new Flight();
flights: Observable<Flight>;
flight_id: number;
constructor(private flightService: FlightService,
private router: Router, private route: ActivatedRoute, private token: TokenStorageService) { }
ngOnInit() {
ngOnInit() {
/* this.flight_id = 1;*/
this.route.params.subscribe(params => { this.flight_id = params['flight_id']; });
this.flightService.getFlight(this.flight_id).subscribe(t => this.flight = t);
this.flight_id = this.flight.flight_id;
this.reloadData();
}
this.reloadData();
}
reloadData() {
this.flights = this.flightService.getFlight(this.flight_id);
}}
flight.ts
export class Flight {
flight_id: number;
departureCity: string;
destinationCity: string;
price: number;
flightDuration: number;
transferNumber: number;
departureDate: Date;
departureTime: Time;
tickets: Ticket[];
}
export class Ticket {
ticket_id: number;
place: number;
user_id: number;
flight_id: number;
}
flight.service.ts
import {Injectable} from '#angular/core';
import {HttpClient} from '#angular/common/http';
import {Observable} from 'rxjs';
import {Flight} from './flight';
#Injectable({
providedIn: 'root'
})
export class FlightService {
private baseUrl = 'http://localhost:8080/api/flights';
constructor(private http: HttpClient) {
}
getFlight(flight_id: number): Observable<Flight> {
return this.http.get<Flight>(`${this.baseUrl}/${flight_id}`);
}
In my Spring Boot it looks like on the picture. Unfortunately, no data for my flight with flight_id=1
Two ways:
Whether You have to subscribe to your service directly to get your data :
this.flightService.getFlight(this.flight_id).subscribe((response) => {
this.flight = response;
});
}
Or, as you'd intended to do using your flights Observable, subscribe also :
reloadData() {
this.flights = this.flightService.getFlight(this.flight_id);
this.flights.subscribe((response) => {
this.flight = response;
});
}}
}}
Need to susbscribe to the getFlight method.
reloadData() {
this.flightService.getFlight(this.flight_id).subscribe((data) => {
this.flights = data
});
}}

How to two-way bind a form value to a nested angular model

I am new to angular or front-end development for that matter. I am trying to two-way bind a form value to a 'nested array fields' of angular model. Unfortunately, it doesn't work and returns undefined or errors. Certainly looks like a blunder to me, please advice on a fix.
Code as follows,
customer.model.ts
export class Customer {
customerID:String;
customerName:String;
contract:Contract[];
}
export class Contract{
customerID: String;
startDate: Date;
endDate: Date ;
conditions: String;
price: Number;
author: String;
}
customer.component.ts
//Package imports
import { Component, OnInit } from '#angular/core';
import { NgForm } from '#angular/forms';
//local imports
import { CustomerService } from '../shared/customer.service';
import { Contract,Customer } from '../shared/customer.model';
declare var M: any;
#Component({
selector: 'app-customer',
templateUrl: './customer.component.html',
styleUrls: ['./customer.component.css'],
providers: [CustomerService]
})
export class CustomerComponent implements OnInit {
constructor(private customerService: CustomerService) { }
ngOnInit() {
this.resetForm();
}
resetForm(form?: NgForm) {
if (form) {
form.reset();
this.customerService.selectedCustomer = {
customerID: "",
customerName: "",
contract: [
{
customerID: "",
startDate: null,
endDate: null,
conditions: "",
price: null,
author: ""
}
]
}
}
}
onSubmit(form: NgForm) {
this.customerService.postCustomer(form.value).subscribe((res) => {
this.resetForm(form);
M.toast({ html: 'Saved successfully', classes: 'rounded' });
});
}
}
customer.service.ts
import { Injectable } from '#angular/core';
import { HttpClient, HttpHeaders } from '#angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/Operatoroperator';
import { Customer,Contract } from './customer.model';
const httpOptions = {
headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};
#Injectable({
providedIn: 'root'
})
export class CustomerService {
selectedCustomer: Customer|{}={};
customers: Customer[];
readonly baseURL = 'http://localhost:3000/customers';
constructor(private http: HttpClient) { }
postCustomer(cust: Customer) {
console.log('front end cust value' + cust + '---' + cust.contract + '----' + cust.customerID + '----' + cust.customerName);
return this.http.post(this.baseURL, cust);
}
}
customer.component.html (only snippet)
Option 1 :
<input type="text" name="startDate" #name="ngModel" [(ngModel)]="customerService.selectedCustomer.contract.startDate"
placeholder="Enter Contract Start Date">
Option 2 :
<input type="text" name="startDate" #name="ngModel" [(ngModel)]="customerService.selectedCustomer.contract[0].startDate"
placeholder="Enter Contract Start Date">
Option 3 :
<input type="text" name="startDate" #name="ngModel" [(ngModel)]="customerService.selectedCustomer.contract[].startDate"
placeholder="Enter Contract Start Date">
Option 4:
<input type="text" name="startDate" #name="ngModel" [(ngModel)]="customerService.selectedCustomer.contract[startDate]"
placeholder="Enter Contract Start Date">