9 Salvataggio della modifica e creazione nuovo utente

Ora dobbiamo prendere i dati del form che abbiamo nell’oggetto e salvarli nell’array tramite la funzione saveUser(), verificando che l’id sia maggiore di 0.

saveUser() {
if (this.user.id > 0) {

}

Inoltre dobbiamo iniettare nel costruttore il servizio UserService, inizializzando private la variabile userService di tipo UserService

userService: UserService;
constructor( userService: UserService) { }

Con questa iniezione nel costruttore diciamo ad angular di aver bisogno del servizio UserService che verrà istanziato se non giò presente, essendo l’inject un singleton.

userService: UserService;
constructor(userService: UserService) { 
  this.userService = userService;
}

Se vogliamo abbreviare possiamo fare la dichiarazione e l’inject insieme aggiungendo private nel costruttore

constructor(private userService: UserService) { }

Ora dobbiamo creare in user-detail un metodo updateUser() per aggiornare i dati dell’utente che riceverà un user di tipo UserInterface, in modo da tipizzare i dati ricevuti.

updateUser(user: UserInterface) {

}

dobbiamo trovare l’utente che ha quel user id selezionato, possiamo utilizzare il metodo per array findIndex() che aspetta in ingresso una funzione che restituisce o true o false in base al valore da cercare.

const idx = this.users.findIndex( );

Per una migliore lettura mettiamo tutto in una costante idx. Tramite un’ arrow function verifichiamo che l’id passato alla funzione pescato dall’array users sia uguale all’id dell’utente selezionato user

const idx = this.users.findIndex( (v) => v.id == user.id);

se idx è diverso da -1, significa che è stato trovato e si potranno aggiornare i dati dell’array passati dal form di modifica

if(idx !== -1 ) {
this.users[idx] = user;
}

ecco la funzione completa updateUser()

updateUser(user: UserInterface) {
 const idx = this.users.findIndex( (v) => v.id === user.id);
 if(idx !== -1 ) {
  this.users[idx] = user;
 }
}

Ora in user-detail possiamo completare la funzione saveUser() utilizzando il metodo updateUser() appena creato

saveUser() {
 if (this.user.id > 0) {
 this.userService.updateUser(this.user);
}
}

Creazione nuovo user

Nell’ app.component aggiungiamo un collegamento per creare un nuovo utente

<a href="#" (click)="newUser()">Nuovo Utente</a>

ora creiamo il metodo newUser() come prima cosa, non sapendo se il form presenta già dei dati, magari in seguito al click sul pulsante modifica, reinizializziamo qundi userSelected come nuovo oggetto di classe User(). Inoltre visualizziamo il form this.showForm = true

newUser() {
 this.userSelected = new User();
 this.showForm = true;
}

Sfruttando la logica di saveUser() che invocava il metodo updateUser se l’id era maggiore di zero ( this.user.id > 0), possiamo aggiungere un else che chiamerà la nuova funzione creteUser()

saveUser() {
 if (this.user.id > 0) {
  this.userService.updateUser(this.user);
 } else {
 }
}

Nel nostro servizio andiamo a creare il metodo createUser() utilizzando il metodo per gli array splice()

createUser(user: UserInterface) {
 this.users.splice(0,0,user);
}

aggiungiamo createUser nell’else di saveUser

saveUser() {
 if (this.user.id > 0) {
  this.userService.updateUser(this.user);
  } else {
     this.userService.createUser(this.user);
  }
}

aggiungiamo un pulsante nel template del form per resettare il form

<button class="reset" (click)="resetForm()">RESET</button>

e creiamo il metodo resetForm() dicendo che se l’id è uguale a zero, allora è un nuovo utente e quindi reinizializzo l’oggetto

resetForm() {
 if (this.user.id == 0) {
  this.user = new User();
 }
}

Template viariable

se invece l’id non è 0, allora è una modifica utente e dobbiamo avere accesso al form, quindi mettiamo un parametro form nel metodo resetForm(form)

resetForm(form) {
 if (this.user.id === 0) {
  this.user = new User();
  } else {

    }
}

adesso nel template del form user-detail aggiungo nel tag <form> una variabile di template che inizia sempre con il cancelletto ( # ) e gli diamo un nome arbitrario, per esempio f di form.

Alla variabile di template assegniamo il valore di ngForm che contiene i dati e le proprietà del form

<form #f="ngForm">

se vogliamo visionare tutte le proprietà presenti nel form, visualizziamo subito il contenuto della proprietà form della template variable #f

<form #f="ngForm">{{f.form | json}}

l’oggetto ci restituisce molte proprietà, per esempio se è stato cliccato un campo, lo stato, se presenta errori…. Se vogliamo accedere ai valori facciamo riferimento alla proprietà value

<form #f="ngForm">{{f.form.value | json}}

ora abbiamo stampati i valori del form e compilando i campi vedremo che cambieranno i valori in tempo reale f.form.value.

Infatti un altra strada che si poteva percorrere era passare nella funzione saveUser() i dati del form tramite value, anzichè tramite user.

Anche per il reset del form possiamo utilizzare il metodo form.reset() di ngForm, quindi sul click reset possiamo passare f.form al metodo resetForm().

<button class="reset" (click)="resetForm(f.form)">RESET</button>

resetForm(form) {
 if (this.user.id === 0) {
  this.user = new User();
  } else {
      form.reset();
    }
}

La differenza è che con la modifica usando ngForm e cliccando su reset, i dati verranno azzerati per quell’id, rischiando di perderli.

Setter e Getter per resettare il form

In user-detail abbiamo il passaggio di dati di user tramite il decoratore @Input, noi possiamo ascoltare questa variabile e creare una copia, per esempio creando una variabile private che riceve il valore di user

private userCopy: User;
@Input() user: User

ora per creare un setter, creiamo un altra variabile privata e mettiamo set davanti alla variabile user che sarà trasformata in una funzione

private userCopy: User;
private __user: User;
@Input() set user(){
}

Questo setter user() riceverà un utente di tipo User e imposterà la variabile di servizio __user uguale ail dato ricevuto

@Input() set user(user: User) {
 this.__user = user;
}

Inoltre mi faccio una copia dei dati da mettere in userCopy col metodo assign(), in modo che quando i dati saranno modificati nel form, non rischierò di perderli col click su reset

@Input() set user(user: User) {
 this.__user = user;
 this.userCopy = Object.assign({}, user);
}

Ora creiamo il getter per recuperare i dati della variabile privata __user

get user() {
 return this.__user;
}

a questo punto quando facciamo il reset impostiamo nell’else il valore di user a userCopy

this.user = this.userCopy;

In questo modo nella modifica non avremo il rischio di perdere i valori originali con il click su reset

resetForm(form) {
 if (this.user.id === 0) {
  this.user = new User();
  } else {
    this.user = this.userCopy;
  }
}