I have a form in html with a submit button. The button has a disabled option that is false only when the form is valid.
<button 
  type="submit" 
  class="btn btn-info btn-fill btn-wd" 
  [disabled]="ragazzoForm.form.invalid">
  Aggiungi Ragazzo
</button>
And it works perfectly. Then i have one of the fields which is a special ID. The id is generated with a function, in the component: genIdReg(). PS: "ragazzoForm" is the name of the form, I declared it in the tag.
<input 
  type="text" 
  class="form-control border-input" 
  readonly 
  name="idreg" 
  [value]="genIdReg(ragazzoForm)" 
  ngModel>
In this function take in input the form, i extract the values i need and then i use another function to cipher it, after that i return the ID.
The problem is that the function cipher does a .toUpperCase() to the string it gets in input. And because the genIdReg() is automatically called even if the form is empty, it returns error like:
RagazziComponent.html:9 ERROR TypeError: Cannot read property 'toUpperCase' of undefined at RagazziComponent.webpackJsonp.../../../../../src/app/ragazzi/ragazzi.component.ts.RagazziComponent.cipher (ragazzi.component.ts:38) at RagazziComponent.webpackJsonp.../../../../../src/app/ragazzi/ragazzi.component.ts.RagazziComponent.genIdReg (ragazzi.component.ts:62) at Object.eval [as updateRenderer] (RagazziComponent.html:14) at Object.debugUpdateRenderer [as updateRenderer] (core.es5.js:13131) at checkAndUpdateView (core.es5.js:12275) at callViewAction (core.es5.js:12638) at execComponentViewsAction (core.es5.js:12570) at checkAndUpdateView (core.es5.js:12276) at callViewAction (core.es5.js:12638) at execEmbeddedViewsAction (core.es5.js:12596) at checkAndUpdateView (core.es5.js:12271) at callViewAction (core.es5.js:12638) at execComponentViewsAction (core.es5.js:12570) at checkAndUpdateView (core.es5.js:12276) at callWithDebugContext (core.es5.js:13493)
So i implemented a control on the validity of the form before executing genIdReg():
genIdReg(form: NgForm) {
  if (!form.form.invalid) {
    console.log("sto generando")
    if (this.magicNumber == null) this.magicNumber = Math.floor(Math.random() * 1000);
    const nome = this.cipher(form.value.nome, this.magicNumber);
    const cognome = this.cipher(form.value.cognome, this.magicNumber);
    const classe = this.cipher(form.value.classe, this.magicNumber);
    console.log(nome, cognome, classe, this.magicNumber);
    return nome + cognome + classe + this.magicNumber;
  } else {
    return "Completa i campi per generare il codice"
  }
}
If the form that's in input is not invalid, then do the things, else return a placeholder. Pay attention at the console.log at line 3.
When i load the page... The value of the input is "Completa i campi per generare il codice", so it seems like it went smoothly. But in the console i get "sto generando". And obviously the above written TypeError, because cipher() is getting called. So it's like if both if and else are called... I can't understand what's wrong with my code...
EDIT: Here the html form code. (The first line is line 9 in the whole file):
<form (submit)="aggiungiRagazzo(ragazzoForm)" #ragazzoForm="ngForm">
                        <div class="row">
                            <div class="col-md-3">
                                <div class="form-group">
                                    <label>ID Registrazione</label>
                                    <input type="text" class="form-control border-input" readonly name="idreg" [value]="idreg" ngModel>
                                </div>
                              </div>
                            <div class="col-md-6">
                                <div class="form-group">
                                    <label for="exampleInputEmail1">Email</label>
                                    <input type="email" class="form-control border-input" placeholder="Email" required name="email" ngModel>
                                </div>
                            </div>
                            <div class="col-md-3">
                                <div class="form-group">
                                    <label for="exampleInputEmail1">Classe</label>
                                    <input type="text" class="form-control border-input" placeholder="Classe" required name="classe" ngModel>
                                </div>
                            </div>
                            <!-- <div class="col-md-3">
                              <div class="form-group">
                                  <label for="exampleInputEmail1">Classe</label>
                                  <select  *ngFor="let classe of classi" type="text" class="form-control border-input"  required name="classe" ngModel>
                                    <option>Prova</option>
                                    </select>
                              </div>
                          </div> //TODO -->
                        </div>
                        <div class="row">
                            <div class="col-md-6">
                                <div class="form-group">
                                    <label>Nome</label>
                                    <input type="text" class="form-control border-input" placeholder="Nome" value="Chet" name="nome" ngModel>
                                </div>
                            </div>
                            <div class="col-md-6">
                                <div class="form-group">
                                    <label>Cognome</label>
                                    <input type="text" class="form-control border-input" placeholder="Cognome" value="Faker" name="cognome" ngModel>
                                </div>
                            </div>
                        </div>
                        <div class="row">
                            <div class="col-md-12">
                                <div class="card card-plain">
                                    <div class="header">
                                        <h4 class="title">Turni in cui non può registrarsi</h4>
                                    </div>
                                    <div class="content table-responsive table-full-width">
                                        <table class="table table-hover">
                                            <thead>
                                                <tr>
                                                    <th *ngFor="let cell of tableData2.headerRow">{{ cell }}</th>
                                                </tr>
                                            </thead>
                                            <tbody>
                                                <tr *ngFor="let row of tableData2.dataRows">
                                                    <td *ngFor="let cell of row">
                                                      <div class="checkbox" style="margin-left: 20px;">
                                                        <input id="checkbox1" type="checkbox" ngModel name={{cell}}>
                                                        <label for="checkbox1">
                                                            {{cell}}
                                                        </label>
                                                      </div></td>
                                                </tr>
                                            </tbody>
                                        </table>
                                    </div>
                                </div>
                            </div>
                        </div>
                        <div class="text-center">
                            <button type="submit" class="btn btn-info btn-fill btn-wd" [disabled]="ragazzoForm.form.invalid">Aggiungi Ragazzo</button>
                        </div>
                        <div class="clearfix"></div>
                    </form>
