In my application,ngOnInit()
loads currencies, categories, and manufacturers. I am using Angular 7 reactive forms for this. Data loads as expected and dropdowns populated with values and the first option selected and showed to the user. So, here is the problem, after finishing form and clicking on submit (using default dropdown values), I see an empty object for the category
, currency
, and manufacturer
.
ProductNewComponent.ts
import {Component, OnInit} from '@angular/core';
import {Router} from '@angular/router';
import {ProductService} from '../service/product.service';
import {FormControl, FormGroup, Validators} from '@angular/forms';
import {CATEGORY_API_URL, CURRENCY_API_URL, MANUFACTURER_API_URL, PRODUCT_API_URL, SERVER_URL} from '../../../app.constants';
import {Product} from '../model/product';
import {Price} from '../model/price';
import {CategoryService} from '../../category/service/category.service';
import {Category} from '../../category/model/category';
import {Currency} from '../model/currency';
import {Manufacturer} from '../model/manufacturer';
@Component({
selector: 'app-product-new',
templateUrl: './product-new.component.html',
styleUrls: ['./product-new.component.css']
})
export class ProductNewComponent implements OnInit
{
categories: Array<Category>;
currencies: Array<Currency>;
manufacturers: Array<Manufacturer>;
productForm = new FormGroup({
id: new FormControl({value:'',disabled:true}, Validators.minLength(2)),
name: new FormControl(''),
description: new FormControl(''),
price: new FormControl(''),
amount: new FormControl(''),
categoryControl: new FormControl(''),
currencyControl: new FormControl( '' ),
manufacturerControl: new FormControl( '' ),
});
constructor(private productService:ProductService, private categoryService:CategoryService,private router:Router) {}
ngOnInit()
{
this.loadCategories();
this.loadCurrencies();
this.loadManufacturers();
}
createProduct()
{
const product=new Product();
product.name=this.productForm.value.name;
product.description=this.productForm.value.description;
product.price=new Price(this.productForm.value.currencyControl, this.productForm.value.price);
product.category=this.productForm.value.categoryControl;
product.manufacturer=this.productForm.value.manufacturerControl;
product.createdBy='Admin';
product.createdDate='';
product.lastModifiedBy='Admin';
product.lastModifiedDate='Admin';
const url=SERVER_URL+PRODUCT_API_URL+'create';
this.productService.createProduct(url,product).subscribe(
value =>
{
console.log('Successfully created product');
},error1 =>
{
console.log('Failed to create product');
},
()=>{
this.router.navigate(['/product/list']);
});
}
private loadCategories()
{
const url=SERVER_URL+CATEGORY_API_URL+'list';
this.categoryService.getCategories(url).subscribe(
categories =>
{
this.categories=categories;
},
error1 =>
{
},
()=>{
});
}
private loadCurrencies()
{
const url=SERVER_URL+CURRENCY_API_URL+'list';
this.productService.getCurrencies( url ).subscribe(
currencies =>
{
this.currencies=currencies;
},
error1 =>
{
},
() =>
{
} );
}
private loadManufacturers()
{
const url=SERVER_URL+MANUFACTURER_API_URL+'list';
this.productService.getManufacturers( url ).subscribe(
manufacturers =>
{
this.manufacturers=manufacturers;
},
error1 =>
{
},
() =>
{
} );
}
manufacturersDataAvailable(): boolean
{
return this.manufacturers!==undefined;
}
categoriesDataAvailable(): boolean
{
return this.categories!==undefined;
}
currenciesDataAvailable(): boolean
{
return this.currencies!==undefined;
}
goBack() {
this.router.navigate(['/product']);
}
}
product.component.html
<div>
<h2>Create New Product</h2>
<br/>
<form [formGroup]="productForm">
<div class="form-group">
<label for="id">Product Id</label>
<input type="text" class="form-control" id="id" formControlName="id">
<small id="emailHelp" class="form-text text-muted">Automatically generated by system</small>
</div>
<div class="form-group">
<label for="name">Name</label>
<input type="text" class="form-control" id="name" formControlName="name" required placeholder="Enter Product Name">
</div>
<div class="form-group">
<label for="description">Description</label>
<input type="text" width="200" height="100" class="form-control" id="description" formControlName="description" required placeholder="Enter Product Description">
</div>
<div class="form-group">
<label for="currencyControl">Price</label> <br/>
<label>
<select class="form-control" formControlName="currencyControl" name="currencyControl" id="currencyControl">
<option *ngFor="let currency of currencies">
{{currency.name}}
</option>
</select>
</label>
<input formControlName="amount" id="amount" placeholder="Enter Product Price (in USD)" required
style="margin: 10px; padding: 5px" type="text">
</div>
<div class="form-group">
<label>Category:
<select class="form-control" name="categoryControl" formControlName="categoryControl">
<option *ngFor="let category of categories">
{{category.name}}
</option>
</select>
</label>
</div>
<div class="form-group">
<label>Manufacturer:
<select class="form-control" formControlName="manufacturerControl" name="manufacturerControl">
<option *ngFor="let manufacturer of manufacturers">
{{manufacturer.name}}
</option>
</select>
</label>
</div>
<button type="submit" class="btn btn-primary" (click)="createProduct()">Submit</button>
<button type="button" class="btn btn-primary" style="margin-left: 30px" (click)="goBack()">Cancel</button>
</form>
</div>
If I change the select statement to use [ngValue]="category"
and when the data loaded from the server I see no default value in dropdowns and throws an error property ng value is not provided by any applicable directives nor by option element