Home > front end >  Angular - cannot use patchvalue for form editing
Angular - cannot use patchvalue for form editing

Time:05-25

I am working on a form where I need to be able to edit the form entry once submitted. As you will see in the code, the form works well, each entry appears well as a line below the form. However, I cannot manage to modify each form entry. If I split the task, it would be to send the data to the form, edit it there and then submit it again.

I think I have to use patchvalue, but I cannot manage to make it work. Any idea? This is my first Angular project and I am bit lost.

Thanks for the help!

Here is the html

<div  >
<h1>Formulario</h1>

<form [formGroup]="person" (ngSubmit)="onsubmit()">
 
  <mat-form-field appearance="fill">
    <label>Introduce tu nombre</label>
    <input matInput #input id="nombre" type="text" placeholder="Nombre (min 3 car)" formControlName="nombre">      
  </mat-form-field>

  <br/>
  <mat-form-field appearance="fill">
    <label>Introduce tus apellidos</label>
    <input matInput #input id="apellidos" type="text" placeholder="Apellidos (min 3 car)" formControlName="apellidos"/>
  </mat-form-field>
  <br/>
<button type = "submit" > Enviar tus datos</button>

    </form>
  </div>



<table>
    <thead>
        <th>Posición</th>
        <th>Nombre</th>
        <th>Apellidos</th>
        <th> Modificar</th>
    </thead>
    <tbody>
        <tr *ngFor="let persona of personas; let i = index">
            <td>{{i}}</td>
            <td>{{persona.nombre}}</td>
            <td>{{persona.apellidos}}</td>
            <td> <button mat-flat-button (click)="edititem(i)" >Modificar</button></td>
      <td>
        </tr>
    </tbody>
</table>

Here is my ts :

    import { Component, OnInit, ViewChild } from '@angular/core';
import { Persona } from 'src/app/components/formulario/persona';
import { FormControl, FormBuilder, FormGroup, Validators, FormGroupDirective, ReactiveFormsModule } from '@angular/forms';
import {MatListModule} from '@angular/material/list';
import { SelectionModel } from '@angular/cdk/collections';


@Component({
  selector: 'app-formulario',
  templateUrl: './formulario.component.html',
  styleUrls: ['./formulario.component.css']
})

export class FormularioComponent implements OnInit {
    person: FormGroup = new FormGroup({});
    personas : Persona[] = [];

    constructor(){
        this.person = new FormGroup({
            nombre : new FormControl("", [Validators.required, Validators.minLength(3)]),
            apellidos : new FormControl("", [Validators.required,  Validators.minLength(3)]),
        });
    }

    ngOnInit() : void{
        }

    onsubmit() {
        let persona = new Persona();

        persona.nombre = this.person.value.nombre;
        persona.apellidos = this.person.value.apellidos;

        this.personas.push(persona);
        this.person.reset();
    }

    edititem(i : number) : void {
            this.person.patchValue({i})
            this.person.get('nombre')?.setValue(this.person.value.nombre)
            this.person.get('apellidos')?.setValue(this.personas[i])

    }

CodePudding user response:

You can pass, futhermore the index the "whole" persona to your edititem function

<button mat-flat-button (click)="edititem(i,persona )" >

Then use a variable "indexEdited" -at last equal to -1, and change your function update like

indexEdited:number=-1;
edititem(i:number,persona:Persona) : void {
     this.person.patchValue(persona)
     this.indexEdited=i;  //<--store the index selected
}

Now in submit you check if indexEdited is equal to -1 to not add else change the array

onsubmit() {
    let persona = new Persona();

    persona.nombre = this.person.value.nombre;
    persona.apellidos = this.person.value.apellidos;

    //check if you're "editing" or not
    if (this.indexEdited==-1)
       this.personas.push(persona);
    else
       this.personas[this.indexEdited]=persona;

    this.indexEdited=-1;  //<--you say that you're not editing
    this.person.reset();
}

NOTE: if your class "Persona" only has properties, use an interface instead of a class. Imagine some like

export interface Persona{
   nombre:string;
   apellidos:string;
}

And you can use in onSubmit some like

const persona:Persona={nombre:this.person.value.nombre,
                      apellidos:this.person.value.nombre
                     }
  • Related