The same form for creating and editing Angular4 data

Here is a form with two input fields bound to a line. The goal was to create the same form for editing and creating data. This has been accomplished, but I am sure that there may be a better way to do this (for example, using AbstractControl functions). I also missed one fix here - if clicking clickEdit() requires updating the form values ​​with the object that the user wants to edit. Thanks for any help and especially for the explanations about AbstractControl and NgModel ..

 <div> <form (ngSubmit)="clicked ? onEditSubmit($event) : onRegisterSubmit($event)" [formGroup] = "form"> <div class="form-group"> <label>Full Name</label> <input type="text" [(ngModel)]="fullname" formControlName="fullname" class="form-control" > </div> <div class="form-group"> <label>Username</label> <input type="text" [(ngModel)]="username" formControlName="username" class="form-control" > </div> <div class="form-group"> <label>Email</label> <input type="text" [(ngModel)]="email" formControlName="email" class="form-control" > </div> <div class="form-group"> <label>Password</label> <input type="password" [(ngModel)]="password" formControlName="password" class="form-control"> </div> <button type="submit" class="btn btn-primary" [disabled]="!form.valid"> Submit </button> </form> </div> <br> <br> <table border="2" class="table table-striped"> <tr> <th>Full Name</th> <th>Username</th> <th>Email</th> <th>Password</th> <th>Delete</th> <th>Edit</th> </tr> <div > </div> <tr *ngFor="let user of userDetails; index as i"> <td>{{user.fullname}}</td> <td>{{user.username}}</td> <td>{{user.email}}</td> <td>{{user.password}}</td> <td><button (click)="userDelete()">X</button></td> <td><button (click)="clickEdit(i)">Edit</button></td> </tr> </table> 

and

 import { Component } from '@angular/core'; import { initializeApp, database } from 'firebase'; import { FormControl, FormGroup, Validators } from '@angular/forms'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'], }) export class AppComponent { fullname : string; username : string; email : string; password : string; clicked = false; userDetails:Array<object>; form; ngOnInit() { this.userDetails=[]; this.form = new FormGroup({ fullname : new FormControl("", Validators.required), username : new FormControl("", Validators.required), email : new FormControl("", Validators.required), password : new FormControl("", Validators.required) }); } onRegisterSubmit(e){ let user = { fullname : this.fullname , username : this.username, email : this.email , password : this.password } this.userDetails.push(user); this.clearInputFields(e); } editIndex = null; clickEdit(i){ this.clicked = !this.clicked; this.editIndex = i; } onEditSubmit(e) { let editUser = { fullname : this.fullname , username : this.username, email : this.email , password : this.password } this.userDetails[this.editIndex] = editUser; this.clearInputFields(e); this.clicked = !this.clicked; } clearInputFields(e){ let all = e.target.querySelectorAll('input'); Object.keys(all).forEach(key => { console.log(all[key].value = ''); }); } } 
+8
source share
1 answer

I would make a few changes to your form. ngModel here is completely redundant as you are using reactive form. Use this instead and remove all ngModel. The object you get from the form corresponds to your user , so what you can do is just push this value as an array.

So, your template should look something like this (abbreviated as the whole code):

 <form (ngSubmit)="onRegisterSubmit(form)" [formGroup] = "form"> <input type="text" formControlName="username" class="form-control" > <input type="submit" class="btn btn-primary" value="Submit" [disabled]="!form.valid"> </form> 

In constructing the form, in this case I used a hidden field, which is also excluded from the form object, since it is disabled . This is an assistant for us, so we can distinguish if this is a new user , or if we are editing user . The value contains the user index from your array. Therefore, if this value exists, we know that to update the object in the array, if this value does not exist, let the user click on the array.

This can be solved in several ways, but above is one of the options.

 this.form = this.fb.group({ index: [{value: null, disabled:true}] username : ['', Validators.required], email : ['', Validators.required], }); 

So, according to the above, we can change onRegisterSubmit to look like this:

 onRegisterSubmit(form) { // since field is disabled, we need to use 'getRawValue' let index = form.getRawValue().index if(index != null) { this.userDetails[index] = form.value } else { this.userDetails.push(form.value) } this.form.reset() // reset form to empty } 

When we want to edit the user, we pass the index and user in the template

 <tr *ngFor="let user of userDetails; let i = index"> <td>{{user.username}}</td> <td>{{user.email}}</td> <td><button (click)="userEdit(user, i)">Edit</button></td> </tr> 

And then we use setValue (or patchValue ) to enter fields with existing values:

 userEdit(user, i) { this.form.setValue({ index: i, username: user.username, email: user.email }) } 

It should be! So, now we can see how much we could simplify your code and get rid of unnecessary things! :)

+12
source

Source: https://habr.com/ru/post/1270308/


All Articles