How To Add New Field in Existing JSON Object Using Angular 10 - html

Hello I’m trying to add a new field (property) to existing json.db object based on a radio button click.
I think this is the best approach because the application has more than one product and some of them don’t have sizes and the other product are using the same model (product) I also don’t want to add a size because the sizes change based on the user clicking on a radio button s , m or l.
Products are being loaded to page from an api which works fine. The issue is when this particular product is added to cart it has to have a size. I am able to get the size value when clicking on one of the radio buttons. My cart component is not a parent or child of the product component
(product-item) to get the size value to be used in the cart I used a BehaviorSubject and I m able to get the size value. What I want to do is when the user click the radio for size and then click add to cart I need to add a field called size into cart object along with the value size to my existing json file.
Right now when add to cart it looks just like Product object. So my approach is to add to the object something like cart.size =sizeValue. object property value. I’m not sure how to accomplish this. Tried of couple of things with no luck. If someone can please point me in the right direction I would be so grateful.
Thanking You in Advance.
json file products object
"products": [
{
"id": 1,
"name": "Overalls",
"description": "Lorem Ipsum is simply dummy text of the printing and
typesetting industry. Lorem Ipsum has been the
industry's standard dummy text ever since the 1500s,
when an unknown printer took a galley of type and
scrambled it to make a type specimen book.",
"imageUrl": "http://localhost:4200/assets/overalls.png",
"price": 250
},
Product model
product.ts
export class Product {
id:number;
name: string;
size: string;
description: string;
price: number;
imageUrl: string;
constructor(id:number, name, description="", size:string, price=0,
imageUrl="" ){
this.id=id
this.name = name
this.description = description
this.price= price
this.size= size
this.imageUrl = imageUrl
}
}
Cart model
cart-item.ts
import { Product } from './product';
export class CartItem {
id: number;
productId: number;
productName: string;
qty: number;
price: number;
size:string;
imageUrl:string;
constructor(id:number, size, product:Product, qty= 1) {
this.id = id;
this.productId = product.id;
this.price = product.price;
this.size = size;
this.productName = product.name;
this.qty = qty;
this.imageUrl = product.imageUrl;
}
}
appservice uses Behavior Subject
appservice.ts
import { Injectable } from '#angular/core';
import { BehaviorSubject } from 'rxjs';
import { FormBuilder, FormGroup, Validators } from '#angular/forms';
#Injectable({
providedIn: 'root'
})
export class AppserviceService {
private data = new BehaviorSubject('');
currentData = this.data.asObservable()
constructor() {
}
updateMessage(item:any){
this.data.next(item);
}
}
cart service
cart.service.ts
#Injectable({
providedIn: 'root'
})
export class CartService {
id: number;
product: any
cartUrl = 'http://localhost:4000/cart';
constructor(private http: HttpClient, private router: Router, private route: ActivatedRoute) {
}
//To do mapping the obtained results out to card items props pipe and mapp functions will be used.
//The observable returneded by carUrl is the source is going to pipe through the map projection anf get results of CartItem
getCartItems(): Observable<CartItem[]> {
return this.http.get<CartItem[]>(cartUrl).pipe(
map((result: any[]) => {
let cartItems: CartItem[] =[];
for(let item of result) {
cartItems.push( new CartItem(item.id, item.size, item.product, item.imageUrl ));
// localStorage.setItem('cartItems',JSON.stringify(cartItems));
sessionStorage.setItem('cartItems',JSON.stringify(cartItems));
}
return cartItems;
})
);
}
addProductToCart(product:Product):Observable<any>{
return this.http.post(cartUrl, {product});
}
}
Product component
product-item.ts
#Component({
selector: 'app-product-item',
templateUrl: './product-item.component.html',
styleUrls: ['./product-item.component.scss']
})
export class ProductItemComponent implements OnInit {
form: FormGroup;
submitted=false;
sizeBy:string;
Valuesize:string;
#Input() productItem:Product
#Input() addedToWishlist: boolean;
//#Input() addedToWishlistitem: boolean = false;
constructor(private msg: MessengerService, private cartService: CartService, private formBuilder: FormBuilder,
private wishlistService:WishlistService, private _wishlistitemService: WishlistItemService,private alertService: AlertService, private _data:AppserviceService) { }
ngOnInit() {
this.form = this.formBuilder.group({
sizeBy: ['', Validators.required]
});
}
// convenience getter for easy access to form fields
get f() { return this.form.controls; }
onSubmit() {
this.submitted = true;
// reset alerts on submit
this.alertService.clear();
// stop here if form is invalid
if (this.form.invalid) {
return;
}
if (!this.form.invalid){
this.Valuesize = this.form.value.sizeBy
this.shareData();
this.handleAddToCart();
}
}
handleAddToCart(){
this.cartService.addProductToCart(this.productItem).subscribe(() =>{
this.msg.sendMsg(this.productItem)
})
}
}
Cart component
cart.component.ts
#Component({
selector: 'app-cart',
templateUrl: './cart.component.html',
styleUrls: ['./cart.component.scss']
})
export class CartComponent {
Valuesize:string;
#Input() product: CartItem;
#Input() cartItem: CartItem
cartItems = [
];
constructor(private msg: MessengerService, private cartService:CartService, private productService: ProductService, private formBuilder:FormBuilder, private _data:AppserviceService) { }
ngOnInit(): void {
this.handleSubscription();
this.loadCartItems();
this._data.currentData.subscribe(currentData => this.Valuesize = currentData)
}
handleSubscription(){
this.msg.getMsg().subscribe((product: Product) => { //This is an obsevable
this.loadCartItems();
})
}
loadCartItems(){
this.cartService.getCartItems().subscribe((items: CartItem[]) => {
this.cartItems = items;
})
}
}
HTML
product-item.component.html
<div class="col-sm-12">
<p class="float-left" style="text-align:left; margin-left:-2px;
width:140px;">{{productItem.name}}</p>
<form [formGroup]="form" (ngSubmit)="onSubmit()">
<div class="float-left form-check" style="font-size:11px; text-
align:left; margin-left: -25px; width:200px">Size:
<alert></alert>
<label class="form-check-label checkbox-inline" for="sizeBy"
style="padding: 4px">
<input type="radio" name="sizeBy" formControlName="sizeBy"
id="small" [ngClass]=f.sizeBy value="S" required >
S</label>
<label class="form-check-label checkbox-inline" for="sizeBy" style="padding: 4px">
<input type="radio" name="sizeBy" formControlName="sizeBy" id="medium" [ngClass]=f.sizeBy value="M" required >
M</label>
<label class="form-check-label checkbox-inline" for="sizeBy" style="padding: 4px">
<input type="radio" name="sizeBy" formControlName="sizeBy" id="large" [ngClass]=f.sizeBy value="L" required>
L</label>
<div *ngIf="f.sizeBy.errors?.required"><b>You Must Coose A</b></div>
<div class="-flex justify-content-between align-items-left">
<div class="btn-group">
<button type="submit" style="border:0; outline:0; background-
color:transparent; padding-bottom: 100px; margin-left: -13px">
<img src="assets/shopping_cart_outline001.png" style="background-
color:none; color:#D30169; font-size:5px; cursor:pointer;
outline:none; outline:0; border:0"></button>
</div>
</div>
</div>
</form>

Related

My codes are not doing get,set,post so what is my codes error how can i fix it?

these are my .ts codes i write these becasue i want to get product details and delete
import { Component, OnInit } from '#angular/core';
import {FormGroup,FormBuilder, FormControl, Validators} from "#angular/forms"
import { ToastrService } from 'ngx-toastr';
import { Product } from 'src/app/models/product';
import { ProductService } from 'src/app/services/product.service';
import { LocalStorageService } from 'src/app/services/local-storage.service';
import { Router } from '#angular/router';
#Component({
selector: 'app-product-delete',
templateUrl: './product-delete.component.html',
styleUrls: ['./product-delete.component.css']
})
export class ProductDeleteComponent implements OnInit {
products: Product[] = [];
dataLoaded = false;
deleteProductForm:FormGroup;
product :Product
productId :number;
constructor(private formBuilder:FormBuilder,
private productService:ProductService
, private toastrService:ToastrService
,private router:Router,
private localStorageService:LocalStorageService) { }
ngOnInit(): void {
this.createdeleteProductForm();
}
createdeleteProductForm(){
this.deleteProductForm = this.formBuilder.group({
productId:["", Validators.required],
})
}
getbyid() {
Number(localStorage)
Number(this.productService)
this.productService.getbyid(Number(localStorage.getItem("productId"))).subscribe(
(response) => {
this.products = response.data;
this.dataLoaded = true;
this.deleteProductForm.setValue({
productId: this.product,
categoryId: this.product.categoryId,
productName: this.product.productName,
unitPrice: this.product.unitPrice
});
},
(responseError) => {
this.toastrService.error(responseError.error);
}
)
}
deleteProduct() {
if (this.deleteProductForm.valid) {
let productModel = Object.assign({}, this.deleteProductForm.value);
productModel.productId=parseInt(productModel.productId);
this.productService.delete(productModel).subscribe(
(response) => {
this.toastrService.success('Lütfen tekrar giriş yapınız');
this.router.navigate(['/login']);
},
(responseError) => {
this.toastrService.error(responseError.error);
}
);
} else {
this.toastrService.error('Bir hata oluştu.');
}
}
}
these are my html codes i trying to do when user sign in a productId after that click the button delete the product in that ıd
<div class="card">
<div class="card-header"><h5 class="title">Ürün Sil</h5></div>
<div class="card-body">
<form [formGroup]="deleteProductForm">
<div class="mb-3">
<label for="productId">ÜrünId'si</label>
<div class="form-group">
<input type="number"
id="productId"
formControlName="productId" class="form-control"
placeholder="productId"/>
</div>
<div class="card-footer" style="background-color: rgb(4, 62, 255)">
<button
class="btn btn-lg btn-outline-success float-end"
(click)="deleteProduct()"
>
Sils
</button>
</div>
and these are my service
delete(product:Product):Observable<ResponseModel>{
let newPath = this.apiUrl + 'products/delete';
return this.httpClient.post<ResponseModel>(newPath, product );
}
getbyid(productId:number) : Observable<ListResponseModel<Product>> {
let newPath = this.apiUrl + 'products/getbyid?productId=' + productId;
return this.httpClient.get<ListResponseModel<Product>>(newPath);
}
what i'm going for is that when the user goes on a productId click the button, I want to delete the data including the Id first, but what's the null time on main at the moment?
note:Value cannot be null. says back-end
in html POST https://localhost:44314/api/products/delete
[HTTP/2 500 Internal Server Error 9591ms gives this error
First of all, have you checked the value of product in the call of delete ?
Also, maybe it's the httpClient.delete you need since it's the best way to delete an object to the back end. I suggest this:
https://angular.io/guide/http#making-a-delete-request

Type error Cannot find properties of undefined (reading id)

I'm at a lost here. I have a couple of services, one has been working for month and the newer one for some weeks, then all of a sudden a couple of days ago I start to get two console errors "Cannot read properties of undefined(reading id). I have not changed anything.
If I can fix one then I can understand the other because they both have the same error. When I did my research it talks about initializing.
This is an e-commerce site, when the user clicks on the heart it gets added to wishlistitems in my json file. The user should have the ability to go to favorites and it shows all of the wishlist items. As I stated it was working now I get errors. I have a two models(class) I have two components wishlist-list and wishlistitems the html will display the url for the images and I have a serive.
Here is the wish Model
import { Product } from './product';
export class Wish {
id:number;
productId: number;
productName: string;
description: string;
qty:number;
price: number;
imageUrl: string;
constructor(id:number, product:Product, qty=1, ){
this.id = id;
this.productId = product.id;
this.price = product.price;
this.productName = product.name;
this.qty = qty;
this.imageUrl = product.imageUrl;
this.description = product.description;
}
}
Here is the Product Model
export class Product {
id:number;
name: string;
description: string;
price: number;
imageUrl: string;
constructor(id:number, name, description="", price=0, imageUrl="" ){
this.id=id
this.name = name
this.description = description
this.price= price
this.imageUrl = imageUrl
}
}
Here is my Wishlist component
import { Component, OnInit, Input } from '#angular/core';
import {ProductService} from 'src/app/services/product.service'
import { MessengerService } from 'src/app/services/messenger.service';
import { WishlistService } from 'src/app/services/wishlist.service';
import { WishlistItemService } from '#app/services/wishlist-item.service';
import { Wish} from 'src/app/models/wish';
import {Product} from 'src/app/models/product';
#Component({
selector: 'app-wishlist-list',
templateUrl: './wishlist-list.component.html',
styleUrls: ['./wishlist-list.component.scss']
})
export class WishlistListComponent implements OnInit {
#Input() product: any;
productList: Product[]= [];
wishitemList: Wish[]= [];
wishItems = [];
constructor( private msg: MessengerService, private productService: ProductService,
private wishlistService: WishlistService,
private _wishlistitemService: WishlistItemService ) { }
ngOnInit(): void {
this.loadwishlistList()
}
loadwishlistList(){
alert("Loading wish list item");
this._wishlistitemService.getWishlistitem().subscribe((items: Wish[]) => {
console.log("A wish List Item" + items);
this.wishItems=items;
})
}
}
Here is my service
#Injectable({
providedIn: 'root'
})
export class WishlistItemService {
product:any;
id:number;
wishlistitemUrl = 'http://localhost:3000/wishlistitem'; //I have this in a api file
constructor(private http: HttpClient) { }
getWishlistitem(): Observable<Wish[]>{
return this.http.get<Wish[]>(wishlistitemUrl).pipe(
map((result: any[]) => {
let wishItems: Wish[] =[];
for(let item of result) {
let productExists = false
for(let i in wishItems){
if(wishItems[i].productId === item.product.id){ //this is line I get error on
wishItems[i].qty++
productExists = true
break;
}
}
if (!productExists){
wishItems.push(new Wish(item.id,item.product, item.name));
}
}
return wishItems;
})
);
}
}
I am at a lost here for it to work then stop working. I'm pulling my hair out, I tried making adjustments but nothing work. I read something about initializing, I'm in need of help.
Thanking You Advance
PH

How do I reload data after deletion?

I have created some posts in my app as html cards. I have a component called PostList, where I am displaying all these cards. On every card I have a delete button to delete that specific card, which works, but after I delete one card, it doesn't disappear from my post list until I manually refresh the page. This is my card:
<div class="card-body">
<h5 class="card-title cut_text">{{post.title}}</h5>
<p class="card-text cut_text" style="text-align: left;">
{{post.text}}
</p>
<span>Read more</span>
<button *appHasRole='["Admin"]' class="ml-5" (click)="deletePost(post.id)" type="button" style="box-shadow: 1px 1px grey;"><em class="fa fa-trash"></em></button>
</div>
And this is the delete function:
#Component({
selector: 'app-post-card',
templateUrl: './post-card.component.html',
styleUrls: ['./post-card.component.css']
})
export class PostCardComponent implements OnInit {
#Input() post: Post;
posts: Post[];
model: any = {};
user: User;
postId: number;
constructor(private postService: PostsService, private toastr: ToastrService,
private route: ActivatedRoute, public accountService: AccountService) {}
ngOnInit(): void {
this.route.params.subscribe((params) => {
console.log(params);
this.postId = params['id'];
});
}
deletePost(id: number) {
this.postService.deletePost(id).subscribe(() =>{
this.toastr.success('Deleted');
}, error => {
console.log(error);
this.toastr.error(error.error);
});
}
}
This is the html of the post list:
<div class=" container mt-3" >
<span *ngFor="let post of posts">
<app-post-card [post]="post" class="item" ></app-post-card>
</span>
</div>
And this is the method to load the posts:
export class PostListComponent implements OnInit {
posts: Post[];
post: Post;
pagination: Pagination;
postParams: PostParams = new PostParams();
constructor(private postService: PostsService) { }
ngOnInit(): void {
this.loadPosts();
}
loadPosts() {
this.postService.getPosts(this.postParams).subscribe(response => {
this.posts = response.result;
this.pagination = response.pagination;
});
}
}
I have tried calling the loadPosts() method after deleting a card, althought it is not very efficient, but it doesn't work, I still have to refresh the page. What can I do so that it automatically disappears after I am deleting it?
You could use #Output from the child component to send the id that was deleted and remove the element corresponding to this id from the posts variable in parent component.
post-card.component.ts
import { Component, Input, Output, EventEmitter } from '#angular/core';
#Component({
selector: 'app-post-card',
templateUrl: './post-card.component.html',
styleUrls: ['./post-card.component.css']
})
export class PostCardComponent implements OnInit {
#Input() post: Post;
#Output() postRemoved = new EventEmitter(); // <-- custom event
posts: Post[];
model: any = {};
user: User;
postId: number;
constructor(private postService: PostsService, private toastr: ToastrService,
private route: ActivatedRoute, public accountService: AccountService) {}
ngOnInit(): void {
this.route.params.subscribe((params) => {
console.log(params);
this.postId = params['id'];
});
}
deletePost(id: number) {
this.postService.deletePost(id).subscribe(() =>{
this.toastr.success('Deleted');
this.postRemoved.emit(id); // <-- emit the id in the event
}, error => {
console.log(error);
this.toastr.error(error.error);
});
}
}
post-list.component.html
<div class=" container mt-3" >
<span *ngFor="let post of posts">
<app-post-card (postRemoved)="onPostRemoved($event)" [post]="post" class="item" ></app-post-card>
</span>
</div>
post-list.component.ts
onPostRemoved(id: any) {
this.posts = JSON.parse(JSON.stringify( // <-- assign a deep clone
this.posts.filter(post => post.id !== id)
));
}

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
});
}}

No provider for ControlContainer and No provider for ControlContainer

I am working on an application using Angular2.
I am trying to use Reactive Forms in my application but I am running into some errors :
The first error is about NgControl as below:
No provider for NgControl ("
div class="col-md-8"
[ERROR ->]input class="form-control"
id="productNameId"
"): ProductEditComponent#16:24
The second error is about ControlContainer as below:
No provider for ControlContainer ("
div
[ERROR ->]div formArrayName="tags">
div class="row">
button cl"):
Htmm file is as below:
<div class="panel panel-primary">
<div class="panel-heading">
{{pageTitle}}
</div>
<div class="panel-body">
<form class="form-horizontal"
novalidate
(ngSubmit)="saveProduct()"
formGroup="productForm" >
<fieldset>
<div class="form-group"
[ngClass]="{'has-error': displayMessage.productName }">
<label class="col-md-2 control-label" for="productNameId">Product Name</label>
<div class="col-md-8">
<input class="form-control"
id="productNameId"
type="text"
placeholder="Name (required)"
formControlName="productName" />
<span class="help-block" *ngIf="displayMessage.productName">
{{displayMessage.productName}}
</span>
</div>
</div>
<div formArrayName="tags">
<div class="row">
<button class="col-md-offset-1 col-md-1 btn btn-default"
type="button"
(click)="addTag()">Add Tag
</button>
</div>
<div class="form-group"
*ngFor="let tag of tags.controls; let i=index" >
<label class="col-md-2 control-label" [attr.for]="i">Tag</label>
<div class="col-md-8">
<input class="form-control"
[id]="i"
type="text"
placeholder="Tag"
formControlName="i" />
</div>
</div>
</div>
<!--more piece of code here -->
My component file is as below:
import { Component, OnInit, AfterViewInit, OnDestroy, ViewChildren, ElementRef } from '#angular/core';
import { FormBuilder, FormGroup, FormControl, FormArray, Validators, FormControlName,NgForm } from '#angular/forms';
import { ActivatedRoute, Router } from '#angular/router';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/observable/fromEvent';
import 'rxjs/add/observable/merge';
import { Observable } from 'rxjs/Observable';
import { Subscription } from 'rxjs/Subscription';
import { IProduct } from './product';
import { ProductService } from './product.service';
import { NumberValidators } from '../shared/number.validator';
import { GenericValidator } from '../shared/generic-validator';
#Component({
templateUrl: './product-edit.component.html'
})
export class ProductEditComponent implements OnInit, AfterViewInit, OnDestroy {
#ViewChildren(FormControlName, { read: ElementRef }) formInputElements: ElementRef[];
pageTitle: string = 'Product Edit';
errorMessage: string;
productForm: FormGroup;
product: IProduct;
private sub: Subscription;
// Use with the generic validation message class
displayMessage: { [key: string]: string } = {};
private validationMessages: { [key: string]: { [key: string]: string } };
private genericValidator: GenericValidator;
get tags(): FormArray {
return <FormArray>this.productForm.get('tags');
}
constructor(private fb: FormBuilder,
private route: ActivatedRoute,
private router: Router,
private productService: ProductService) {
// Defines all of the validation messages for the form.
// These could instead be retrieved from a file or database.
this.validationMessages = {
productName: {
required: 'Product name is required.',
minlength: 'Product name must be at least three characters.',
maxlength: 'Product name cannot exceed 50 characters.'
},
productCode: {
required: 'Product code is required.'
},
starRating: {
range: 'Rate the product between 1 (lowest) and 5 (highest).'
}
};
// Define an instance of the validator for use with this form,
// passing in this form's set of validation messages.
this.genericValidator = new GenericValidator(this.validationMessages);
}
ngOnInit(): void {
this.productForm = this.fb.group({
productName: ['', [Validators.required,
Validators.minLength(3),
Validators.maxLength(50)]],
productCode: ['', Validators.required],
starRating: ['', NumberValidators.range(1, 5)],
tags: this.fb.array([]),
description: ''
});
// Read the product Id from the route parameter
this.sub = this.route.params.subscribe(
params => {
let id = +params['id'];
this.getProduct(id);
}
);
}
ngOnDestroy(): void {
this.sub.unsubscribe();
}
ngAfterViewInit(): void {
// Watch for the blur event from any input element on the form.
let controlBlurs: Observable<any>[] = this.formInputElements
.map((formControl: ElementRef) => Observable.fromEvent(formControl.nativeElement, 'blur'));
// Merge the blur event observable with the valueChanges observable
Observable.merge(this.productForm.valueChanges, ...controlBlurs).debounceTime(800).subscribe(value => {
this.displayMessage = this.genericValidator.processMessages(this.productForm);
});
}
addTag(): void {
this.tags.push(new FormControl());
}
getProduct(id: number): void {
this.productService.getProduct(id)
.subscribe(
(product: IProduct) => this.onProductRetrieved(product),
(error: any) => this.errorMessage = <any>error
);
}
onProductRetrieved(product: IProduct): void {
if (this.productForm) {
this.productForm.reset();
}
this.product = product;
if (this.product.id === 0) {
this.pageTitle = 'Add Product';
} else {
this.pageTitle = `Edit Product: ${this.product.productName}`;
}
// Update the data on the form
this.productForm.patchValue({
productName: this.product.productName,
productCode: this.product.productCode,
starRating: this.product.starRating,
description: this.product.description
});
this.productForm.setControl('tags', this.fb.array(this.product.tags || []));
}
deleteProduct(): void {
if (this.product.id === 0) {
// Don't delete, it was never saved.
this.onSaveComplete();
} else {
if (confirm(`Really delete the product: ${this.product.productName}?`)) {
this.productService.deleteProduct(this.product.id)
.subscribe(
() => this.onSaveComplete(),
(error: any) => this.errorMessage = <any>error
);
}
}
}
saveProduct(): void {
if (this.productForm.dirty && this.productForm.valid) {
// Copy the form values over the product object values
let p = Object.assign({}, this.product, this.productForm.value);
this.productService.saveProduct(p)
.subscribe(
() => this.onSaveComplete(),
(error: any) => this.errorMessage = <any>error
);
} else if (!this.productForm.dirty) {
this.onSaveComplete();
}
}
onSaveComplete(): void {
// Reset the form to clear the flags
this.productForm.reset();
this.router.navigate(['/products']);
}
}
I am trying to solve this problem for more than 2 days but I still do not have a solution. I have seen many other answers in stackoverflow but none of them is solving my problem.
Import both Forms Module and ReactiveFormsModule from #angular/forms in the file app.module.ts