I'm pretty much at wit's end with this now, Trying to build an application that tracks hours for timesheets, The logic so far all works all the calculations seem right for hours but for whatever reason the form is creating 2 objects when it's submitted and i have absolutely zero idea why.
Here's what gets outputted to console on form submit, The data's all correct and lines up with what's in the form but it's duplicated, and i have absolutely no idea why;
day-app.component.ts:44 Object {date: "2016-08-08", startTime: "09:00", endTime: "17:30", client: "qwe", project: "qwe"…}
day-app.component.ts:44 Object {date: "2016-08-08", startTime: "09:00", endTime: "17:30", client: "qwe", project: "qwe"…}
Day.ts - Object for holding the data for each day logged
export class Day {
id: number;
date: Date;
startTime: Date;
endTime: Date;
hours: number;
client: string;
project: string;
task: string;
}
Day.service.ts - The class used to store incoming data
import { Injectable } from '#angular/core';
import { Day } from './day';
#Injectable()
export class DayService {
lastId: number = 0;
public days = [];
addDay(day): void {
this.days.push(day);
}
Day-app.component.ts - The component used to render the views and forms and send form data onto the Day Service for storage
import { Component } from '#angular/core';
import { DayService } from '../day.service';
import { Day } from '../day';
#Component({
moduleId: module.id,
selector: 'app-day-app',
templateUrl: 'day-app.component.html',
styleUrls: ['day-app.component.css'],
providers: [DayService],
})
export class DayAppComponent {
constructor(private dayService: DayService) {
}
// Can access methods from DayService;
// dayService.method
// formService.method
get days() {
return this.dayService.getAllDays();
}
onSubmit(form): void {
let formData = form;
let timesTotal = (formData.startTime-formData.endTime*24);
let startDate = new Date(Date.parse(formData.date + " " + formData.startTime));
let endDate = new Date(Date.parse(formData.date + " " + formData.endTime));
let timeDiff = (((endDate.getTime()-startDate.getTime())/3600)/1000);
let newDay = {
date : formData.date,
startTime : formData.startTime,
endTime : formData.endTime,
client : formData.client,
project : formData.project,
hours : timeDiff
};
console.log(newDay);
this.dayService.addDay(newDay);
}
}
Day-app.component.html
<form #f="ngForm"
(ngSubmit)="onSubmit(f.value)"
class="form">
<div class='input-group'>
<div class='row'>
<div class='col-sm-12 col-md-12'>
<div class='col-sm-6 col-md-6'>
<label>Date to add</label>
<input type='date'
name='date'
placeholder='What date did you work?'
class='form-control'
ngModel />
<br />
<label>Client</label>
<input type='text'
name='client'
placeholder='Which client were you working for?'
class='form-control'
ngModel />
<br>
</div>
<div class='col-sm-6 col-md-6'>
<div class='row'>
<div class='col-sm-6 col-md-6'>
<label>Clocked In</label>
<input type='time'
name='startTime'
placeholder='Punch in time'
class='form-control'
ngModel />
</div>
<div class='col-sm-6 col-md-6'>
<label>Clocked Out</label>
<input type='time'
name='endTime'
placeholder='Punch out time'
class='form-control'
ngModel />
</div>
</div>
<label>Project</label>
<input type='text'
name='project'
placeholder='Which project were you working on?'
class='form-control'
ngModel />
</div>
</div>
<hr />
</div>
</div>
<br>
<input class='btn btn-sm btn-success' autofocus="" type='submit' value='Add Day' />
</form>
Related
While working on Angular 2 form submit I run into a problem. When I create an object inside a component everything works well and my form gets submit via post method. But when I am using an object from a class outside the component my form sends a get request with url http://localhost:4200/blog?title=sss&content=ssssss
Does anyone know why this is happening?
Template:
<form (ngSubmit)="onSubmit()" #f="ngForm">
<!-- <form #f="ngForm" (ngSubmit)="onSubmit(f)">-->
<div class="form-group">
<label for="title">Tytuł</label>
<textarea class="form-control" id="title" rows="1"
ngModel name = "title" required minlength="3" #title="ngModel"></textarea>
<span class="help-block" *ngIf="!title.valid && title.touched">Wprowadzono za krótki tekst (minum to 3 znaki).</span>
<label for="content">Zawartość:</label>
<textarea class="form-control" id="content" rows="3"
ngModel name = "content" required minlength="3" #content="ngModel"></textarea>
<span class="help-block" *ngIf="!content.valid && content.touched">Wprowadzono za krótki tekst (minum to 3 znaki).</span>
</div>
<button type="submit" class="btn btn-primary"
[disabled] ="!f.valid"
>Wyślij</button>
</form>
Component:
import {Component, OnInit, ViewChild} from '#angular/core';
import {NgForm} from "#angular/forms";
import {Blog} from "../../shared/blog";
import {BlogService} from "../../services/blog.service";
#Component({
selector: 'app-blog-form',
templateUrl: './blog-form.component.html',
styleUrls: ['./blog-form.component.css']
})
export class BlogFormComponent implements OnInit {
#ViewChild('f') form: NgForm;
errorMessage: string;
/* this works well
blog = {
title: '',
content: '',
dateCreated: ''
}*/
//this doesn't work
blog: Blog;
ngOnInit(){}
onSubmit(){
this.blog.title = this.form.value.title;
this.blog.content = this.form.value.content;
}
}
The Blog class. I tried both this:
export class Blog {
constructor(public title = '', public content = '', public dateCreated = ''){}}
And this:
export class Blog {
constructor(public title : string, public content : string, public dateCreated : string){}}
Thanks for any help :)
I am not sure why this is happening but try not using this.form.value.
onSubmit(){
this.blog.title = this.form.title;
this.blog.content = this.form.content;
console.log(this.blog);
}
Use of value posts back your page. Now this code should work.
There are other questions out there about uploading images with Angular 4, but NO comprehensive answers. I have played around with ng2-file-upload and angular2-image-upload, but can't get them to save in my Mongo/Mongoose DB. Here is what I have to far...
Component HTML:
<form (submit)="newProduct(formData)" #formData="ngForm">
<div class="form-group">
<label for="name">Product Name:</label><input type='text' name='name' class="form-control" id="name" ngModel>
</div>
<div class="form-group">
<label for="image">Image:</label><input type="file" name='image' class="form-control" id="image" ngModel>
</div>
<div class="form-group">
<label for="description">Description:</label><input type='text' name='description' class="form-control" id="description" ngModel>
</div>
<div class="form-group">
<label for="quantity">Quantity:</label><input type='number' name='quantity' class="form-control" id="quantity" ngModel>
</div>
<button type="submit" class="btn btn-default">Add</button>
</form>
Component.ts
import { Component, OnInit } from '#angular/core';
import { AddService } from './add.service';
...
export class AddComponent implements OnInit {
constructor(private _addService:AddService) { }
ngOnInit() {
}
newProduct(formData){
this._addService.addProduct(formData.value)
.then(()=>{
formData.reset()
})
.catch(err=>console.log(err))
}
}
Compoenent service
import { Injectable } from '#angular/core';
import { Http, Response } from '#angular/http';
import 'rxjs';
#Injectable()
export class AddService {
constructor(private _http:Http) { }
addProduct(newprod){
return this._http.post('/api/newprod', newprod).map((prod:Response)=>prod.json()).toPromise();
}
}
Controller
addProduct:(req,res)=>{
let newProd = new Product(req.body);
newProd.save((err,savedProd)=>{
if(err){
console.log("Error saving product");
} else {
res.json(savedProd);
}
})
},
Schema:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var ProductSchema = new Schema({
name: {type:String,required:true},
image: {data:Buffer, contentType:String},
description: {type:String,required:true},
quantity: {type:Number,required:true},
}, {timestamps:true})
var Product = mongoose.model('Product', ProductSchema);
All of the other inputs make it back to the DB fine. What do I need to do to get the images saving properly?
I am afraid you can't directly upload image like that. First you can access image data from file tag and assign into formdata.
you can try like this.In your component
newProduct(formData){
let inputEl: HTMLInputElement = this.el.nativeElement.querySelector('#image');
let fileCount: number = inputEl.files.length;
let formData = new FormData();
if (fileCount > 0) {
formData.append('image', inputEl.files.item(0));
}
this._addService.addProduct(formData.value)
.then(()=>{
formData.reset()
})
.catch(err=>console.log(err))
}
}
this is not exact working solution but you can start like this.
Hi i have a question about Angular 2 and really don't know how to do that and I need your help :)
I have a child component that have a simple registration form but the submit button on parent template. So when I press the submit button it will get data from child component form.
here is my example.
Parent component ts
import {Component, ViewChild, OnDestroy, Output, EventEmitter} from '#angular/core';
import {GlobalEvent} from 'app/shared/GlobalEvent';
#Component({
selector: 'signup',
templateUrl: 'SignUpModalComponent.html',
styleUrls: ['SignUpModalComponent.scss'],
})
export class SignUpModalComponent implements OnDestroy {
public overlayState: boolean;
public step: number = 1;
public formSubmit: boolean;
#ViewChild('firstModal')
modal: any;
constructor(private modalEventService: GlobalEvent) {
this.modalEventService.modalChangeEvent.subscribe((res: boolean) => {
this.overlayState = res;
if (res) {
this.modal.open();
} else {
this.modal.close();
}
});
}
closeModal(value: boolean): void {
this.modalEventService.close(false);
this.modal.close()
}
ngOnDestroy() {
this.modalEventService.modalChangeEvent.unsubscribe();
}
incrementStep():void {
this.step += 1;
}
decrementStep():void {
this.step -= 1;
}
onFormSubmit(): void {
this.formSubmit = true;
}
}
Parent component html template
<div class="modal-overlay" *ngIf="overlayState"></div>
<modal (onClose)="closeModal(false)" #firstModal >
<modal-header>
<button (click)="firstModal.close()" class="close-btn"><i class="material-icons">close</i></button>
<div class="steps-container">
<span [ngClass]="{'active': step == 1 }">1</span>
<span [ngClass]="{'active': step == 2 }">2</span>
<span [ngClass]="{'active': step == 3 }">3</span>
<span [ngClass]="{'active': step == 4 }">4</span>
</div>
</modal-header>
<modal-content>
<signup-form [hidden]="step != 1" [formSubmit]="formSubmit"></signup-form>
<signup-social ngClass="social-step{{step}}" [step]="step"></signup-social>
</modal-content>
<modal-footer>
<button md-button (click)="decrementStep()" [hidden]="step == 1"><Back</button>
<button md-button (click)="incrementStep(); onFormSubmit()" [hidden]="step != 1">Next></button>
<button md-button (click)="incrementStep()" [hidden]="step == 1 || step == 4">Skip</button>
</modal-footer>
</modal>
Child component ts file
import {Component, OnInit, Input} from '#angular/core';
import {FormBuilder, FormGroup, Validators} from '#angular/forms';
import {CustomValidators} from 'ng2-validation';
import {SignUpFormInterface} from './SignUpFormInterface';
#Component({
selector: 'signup-form',
templateUrl: 'SignUpForm.html',
styleUrls: ['SignUpForm.scss']
})
export class SignUpForm implements OnInit {
signupInfo: FormGroup;
public tmppass: any;
#Input() set formSubmit(sendData: boolean) {
if (sendData) {
}
}
constructor(private formbuilder: FormBuilder) {
}
ngOnInit() {
this.signupInfo = this.formbuilder.group({
email: ['', [CustomValidators.email]],
username: ['', [Validators.required, CustomValidators.min(10)]],
password: ['', [Validators.required, CustomValidators.rangeLength([5, 100]), this.setPass]],
confirmPassword: ['', [Validators.required, CustomValidators.rangeLength([5, 100]), CustomValidators.equal(this.tmppass)]],
fullName: ['', [Validators.required, CustomValidators.min(10)]],
gender: ['', [Validators.required]],
countrys: ['', [Validators.required]],
});
}
setPass(c: any): void {
console.log('sdsd', c.value);
if (c.value) {
this.tmppass = '';
this.tmppass = <string>c.value;
}
}
onSubmit({value, valid}: {value: SignUpFormInterface, valid: boolean}) {
console.log(this.signupInfo);
}
cons() {
console.log(this.signupInfo);
}
}
function validateEmail(c: any) {
let EMAIL_REGEXP = /^[A-Z0-9._%+-]+#[A-Z0-9.-]+\.[A-Z]{2,4}$/i;
return EMAIL_REGEXP.test(c.value) ? c.email = false : c.email = true;
}
Child component html template
<div class="sign-up-form clearfix">
<form novalidate (ngSubmit)="onSubmit(signupInfo)" [formGroup]="signupInfo">
<label>
<input type="file" placeholder="Last Name*" name="lastName"/>
upload an avatar
</label>
<md-input-container>
<input md-input placeholder="Email address*" name="email" formControlName="email"/>
</md-input-container>
<!--<p *ngIf="signupInfo.controls.email.errors?.email">error message</p>-->
<div class="errror-msg" *ngIf="signupInfo.controls.email.errors?.email">
<md-hint>
<span>Name should be minimum 6 characters</span>
</md-hint>
</div>
<p *ngIf="signupInfo.controls.username.errors?.min">error message</p>
<div class="input-wrap" [ngClass]="{'error': signupInfo.controls.username.errors?.min}">
<md-input-container>
<input md-input placeholder="Username*" name="username" formControlName="username"/>
</md-input-container>
<div class="errror-msg" *ngIf="signupInfo.controls.username.errors?.min">
<md-hint>
<span>Name should be minimum 6 characters</span>
</md-hint>
</div>
<div class="errror-msg"
*ngIf="signupInfo.get('username').hasError('minlength') && signupInfo.get('username').touched">
<md-hint>
<span>Name should be minimum 6 characters</span>
</md-hint>
</div>
</div>
<p *ngIf="signupInfo.controls.password.errors?.rangeLength">error xcdfdfd</p>
<md-input-container>
<input md-input placeholder="Password*" formControlName="password"/>
</md-input-container>
<p *ngIf="signupInfo.controls.confirmPassword.errors?.rangeLength">error password</p>
<p *ngIf="signupInfo.controls.confirmPassword.errors?.equal">error equal</p>
<md-input-container>
<input md-input placeholder="Confirm Password*" formControlName="confirmPassword"/>
</md-input-container>
<p *ngIf="signupInfo.controls.fullName.errors?.min">error password</p>
<md-input-container>
<input md-input placeholder="Full Name*" name="fullName" formControlName="fullName"/>
</md-input-container>
<p *ngIf="signupInfo.controls.gender.errors?.required">error password</p>
<md-select placeholder="Gender" formControlName="gender">
<md-option *ngFor="let food of ['react','angular']" [value]="food">
{{ food }}
</md-option>
</md-select>
<p *ngIf="signupInfo.controls.countrys.errors?.required">error password</p>
<md-select placeholder="Country" formControlName="countrys">
<md-option *ngFor="let country of countrys" [value]="country">
{{ country.name }}
</md-option>
</md-select>
<div class="input-wrap">
<md-input-container placeholder="Date of Birth *">
<input md-input placeholder="mm/dd/yyyy" type="text" name="DateofBirth"/>
</md-input-container>
</div>
</form>
</div>
Thanks for help :)
I am busy with a Stock take form that needs to be posted to a REST API. I have a stockTake model which has three fields that get initialized with default values of 0. the three fields "StockTakeID, IDKey and PackSize" are not part of the angular form where the data needs to be entered. My issue is submitting the model with those three fields with default values to my RestService. When I submit the stockTakeForm.value I get an error as those three fields are not part of the data that's being submitted... Any idea how I can go about getting this to work?
my stock-take.model.ts:
export class StockTakeModel {
constructor(
StockTakeID: number = 0,
IDKey: number = 0,
BarCode: number,
ProductCode: string,
SheetNo: string,
BinNo: string,
Quantity: number,
PackSize: number = 0) { }
}
my stock-take.component.ts:
import { Component, OnInit } from '#angular/core';
import { FormBuilder, FormGroup, Validators } from '#angular/forms';
import { RestService } from '../../services/rest.service';
import { StockTakeModel } from '../../models/stock-take.model';
#Component({
selector: 'stock-take',
templateUrl: './stock-take.component.html',
styleUrls: ['./stock-take.component.css']
})
export class StockTakeComponent implements OnInit {
stockTakeForm: FormGroup;
constructor(private fb: FormBuilder, private restService: RestService) {
this.stockTakeForm = fb.group({
'sheetNo':['', Validators.required],
'binNo':['', Validators.required],
'barcode':['', Validators.required],
'Qty':['', Validators.required]
});
}
submitStockTake(stockTakeModel: StockTakeModel) {
//console.log(stockTakeModel);
this.restService.postStockTake(stockTakeModel)
.subscribe(
(res) => {
console.log(res);
},
(res) => {
console.log("failure: " + res);
}
);
this.stockTakeForm.reset();
}
ngOnInit() {
}
}
my stock-take.component.html:
<div class="row">
<div class="col-md-6 col-md-push-3">
<h1>Stock Take</h1>
<br /><br />
<form [formGroup]="stockTakeForm" role="form" (ngSubmit)="submitStockTake(stockTakeForm.value)">
<input type="text" placeholder="Enter Sheet Number" class="form-control" id="sheetNo" [formControl]="stockTakeForm.controls['sheetNo']" name="sheetNo">
<input type="text" placeholder="Enter Bin Number" class="form-control" id="binNo" [formControl]="stockTakeForm.controls['binNo']" name="binNo">
<input type="number" placeholder="Enter Barcode" class="form-control" id="bCode" [formControl]="stockTakeForm.controls['barcode']" name="barcode">
<input type="number" placeholder="Enter Quantity" clas="form-control" id="Qty" [formControl]="stockTakeForm.controls['Qty']" name="quantity">
<button class="btn btn-block" [disabled]="!stockTakeForm.valid">Submit</button>
</form>
</div>
</div>
updated stock-take.component:
import { Component, OnInit } from '#angular/core';
import { FormBuilder, FormGroup, Validators } from '#angular/forms';
import { RestService } from '../../services/rest.service';
import { StockTakeModel } from '../../models/stock-take.model';
#Component({
selector: 'stock-take',
templateUrl: './stock-take.component.html',
styleUrls: ['./stock-take.component.css']
})
export class StockTakeComponent implements OnInit {
stockTakeForm: FormGroup;
stockTakeModel: StockTakeModel;
constructor(private fb: FormBuilder, private restService: RestService) {
this.stockTakeForm = fb.group({
'sheetNo':['', Validators.required],
'binNo':['', Validators.required],
'barcode':['', Validators.required],
'Qty':['', Validators.required]
});
}
doStockTake(val: any) {
//console.log("val:" + JSON.stringify(val));
this.stockTakeModel = new StockTakeModel(0, 0, val[Object.keys(val)[2]], '', val[Object.keys(val)[0]], val[Object.keys(val)[1]], val[Object.keys(val)[3]], 0);
// console.log(this.stockTakeModel);
console.log(JSON.stringify(this.stockTakeModel));
}
submitStockTake(stockTakeModel: StockTakeModel) {
//console.log(stockTakeModel);
this.restService.postStockTake(stockTakeModel)
.subscribe(
(res) => {
console.log(res);
},
(res) => {
console.log("failure: " + res);
}
);
this.stockTakeForm.reset();
}
ngOnInit() {
}
}
One workaround would to create a new variable, e.g:
stockTakeModel: StockTakeModel;
if that doesn't work (as you said it complained about undefined), you can also instantiate it as an empty Object, like so:
stockTakeModel = {};
EDIT, so you changed your code to something like this: I also added some console.logs to show where it is undefined, as there was a little question about that.
stockTakeModel: StockTakeModel; // undefined at this point (or empty if you have defined it as empty above)!
// use Object keys to access the keys in the val object, a bit messy, but will work!
submitStockTake(val: any) {
this.stockTakeModel =
new StockTakeModel(0, 0, val[Object.keys(val)[2]], '', val[Object.keys(val)[0]],
val[Object.keys(val)[1]], val[Object.keys(val)[3]]);
// console.log(this.StockTakeModel); // now it should have all values!
this.restService.postStockTake(this.stockTakeModel)
.subscribe(d => { console.log(d)} ) // just shortened your code a bit
this.stockTakeForm.reset();
}
EDIT: So finally the last issue is solved, besides the solution above. It's because your StockTakeModel-class wasn't properly declared the value was undefined, or actually empty. So fix your class to:
export class StockTakeModel {
constructor(
public StockTakeID: number = 0, // you were missin 'public' on everyone
public IDKey: number = 0,
public BarCode: number,
public ProductCode: string,
public SheetNo: string,
public BinNo: string,
public Quantity: number,
public PackSize: number = 0) { }
}
Note also that in your 'updated' code you still have (ngSubmit)="submitStockTake(stockTakeForm.value) in your form, so your created doStockTake-method is not called.
I don't understand the construction [formControl] in your template.
There should be at least [ngModel].
Usualy I use, for two-way communication, the [(ngModel)]. Not the [formControl].
So your template code should look like this:
<div class="row">
<div class="col-md-6 col-md-push-3">
<h1>Stock Take</h1>
<br /><br />
<form [formGroup]="stockTakeForm" role="form" (ngSubmit)="submitStockTake(stockTakeForm.value)">
<input type="text" placeholder="Enter Sheet Number" class="form-control" id="sheetNo" [(ngModel)]="stockTakeForm.controls['sheetNo']" name="sheetNo">
<input type="text" placeholder="Enter Bin Number" class="form-control" id="binNo" [(ngModel)]="stockTakeForm.controls['binNo']" name="binNo">
<input type="number" placeholder="Enter Barcode" class="form-control" id="bCode" [(ngModel)]="stockTakeForm.controls['barcode']" name="barcode">
<input type="number" placeholder="Enter Quantity" clas="form-control" id="Qty" [(ngModel)]="stockTakeForm.controls['Qty']" name="quantity">
<button class="btn btn-block" [disabled]="!stockTakeForm.valid">Submit</button>
</form>
</div>
</div>
I have a repeating Form for every CustomerProject. The repeating form shows all the Projects for a Customer. If i have for example 5 project forms, i want to edit 3 and add 2 and hit submit, posting / putting everything at once.
The question is how do i accomplish this?
Form HTML:
<form [formGroup]="myForm" novalidate (ngSubmit)="save(myForm)">
<!--projects-->
<div formArrayName="projects">
<div *ngFor="let project of myForm.controls.projects.controls; let i=index" class="panel panel-default">
<div class="panel-heading">
<span>Project {{i + 1}}</span>
<span class="glyphicon glyphicon-remove pull-right" *ngIf="myForm.controls.projects.controls.length > 1" (click)="removeProject(i)"></span>
</div>
<div class="panel-body" [formGroupName]="i">
<div class="form-group col-xs-6">
<label>Customer</label>
<input type="text" class="form-control" formControlName="customer_id">
<small [hidden]="myForm.controls.projects.controls[i].controls.customer_id.valid" class="text-danger">
Street is required
</small>
</div>
<div class="form-group col-xs-6">
<label>Project</label>
<input type="text" class="form-control" formControlName="project">
</div>
</div>
</div>
</div>
<div class="margin-20">
<a (click)="addProject()" style="cursor: default">
Add another project +
</a>
</div>
<div class="margin-20">
<button type="submit" class="btn btn-inverse pull-right" [disabled]="!myForm.valid">Submit</button>
</div>
Typescript
public myForm: FormGroup;
private projects: CustomerProject[];
private project: CustomerProject;
private showForm: boolean = false;
#Input() customer: Customer = new Customer(1, '', '', '', '', '', '', '');
#Input() listId: string;
#Input() editId: string;
constructor(
private _fb: FormBuilder,
private authService: AuthService,
private projectService: CustomerProjectService
) { }
loadProjects() {
this.projectService.getCustomerProjects(this.customer.id)
.subscribe(projects => {
this.projects = projects;
console.log(this.project);
this.initForm();
},
err => {
console.error(err);
this.authService.tokenValid();
})
}
initForm() {
this.myForm = this._fb.group({
projects: this._fb.array([])
});
// add existing customer projects
this.addProjects();
//this.addProject('', '');
this.showForm = true;
}
ngOnInit() {
this.loadProjects();
}
ngOnChanges(changes) {
EmitterService.get(this.editId).subscribe((customer: Customer) => {
this.customer = customer;
this.loadProjects();
});
}
initProject(customer_id: string, project: string) {
return this._fb.group({
customer_id: [customer_id],
project: [project]
})
}
addProject(customer_id: string, project: string) {
const control = <FormArray>this.myForm.controls['projects'];
control.push(this.initProject(customer_id, project));
}
addProjects() {
for (var i = 0; i < this.projects.length; i++){
this.project = this.projects[i];
var customer_id = this.project.customer_id;
var project = this.project.project;
this.addProject(customer_id, project);
}
}
removeProject(i: number) {
const control = <FormArray>this.myForm.controls['projects'];
control.removeAt(i);
}
save(model: any) {
}
Its not recommended to posting forms at once.
UI: it gets too way complex. showing multiple forms makes users baffled.
UX: users expect add, edit or remove does CRUD at the moment and would not wait to press submit button.
Software Architecture: it violates separation of concern principle.