typescript - Angular 2 FormBuilder-fel under instansiering
(Koden har uppdaterats med fix)
Jag försöker bygga ett formulär och lägga till validering på en kontrollgrupp så att jag kan kontrollera om kombinationen av två kontroller finns i en matris av objekt. Jag har följande kod, men när jag försöker köra min sida får jag ett fel.
UNDANTAG: Fel vid instansiering av ClientFormComponent!. ORIGINALT UNDANTAG: TypeError: Kan inte läsa egenskapen 'length' av undefined
Jag är osäker på varför det inte går att komma åt längdegenskapen för min array. Metoden "getClients()" i min tjänst fungerar helt felfritt på andra ställen i min app. Alla tankar vore uppskattade.
@Component({
selector: 'client-form',
templateUrl: './Scripts/typescript/client-form.component.html',
directives: [FORM_DIRECTIVES],
providers: [ClientService]
})
export class ClientFormComponent
{
clientForm: ControlGroup;
npi: AbstractControl;
name: AbstractControl;
constructor(private _clientService: ClientService, _fb: FormBuilder) {
this.clientForm = _fb.group({ 'name': ['', Validators.compose([Validators.required])], 'npi': ['', Validators.compose([Validators.required, npiNumValidator, Validators.maxLength(10), Validators.minLength(10)])] }, { asyncValidator: this.npiNameDupValidator.bind(this) });
this.name = this.clientForm.controls['name'];
this.npi = this.clientForm.controls['npi'];
}
clientList: Client[];
active = true;
onSubmit(value: Client) {
this._clientService.addDeleteClient(value, true)
.subscribe(
client => this.clientList.push(client));
}
npiNameDupValidator(group: ControlGroup) {
return new Promise((resolve, reject) => {
let name = group.controls['name'];
let npi = group.controls['npi'];
var found = false;
this._clientService.getClients().subscribe(clients => {
for (var i = 0; i < clients.length; i++) {
alert(clients[i].name + ':' + name.value);
alert(clients[i].npi + ':' + npi.value);
if (clients[i].name == name.value && clients[i].npi == npi.value) {
found = true;
break;
}
}
if (found) {
alert('Found!');
resolve({ npiNameDupe: true });
}
else {
resolve(null);
}
});
});
}
}
function npiNumValidator(control: Control): { [s: string]: boolean } {
if (isNaN(control.value)) {
return { npiNAN: true };
}
}Min mall HTML:
<div class="container">
<form *ngIf="active" (ngSubmit)="onSubmit(clientForm.value)" [ngFormModel]="clientForm">
<div class="form-group" style="float: left;">
<label for="clientid">Client Id:</label>
<input placeholder="QDX"id="clientid" type="text" class="form-control" [ngFormControl]="clientForm.controls['name']">
<div *ngIf="name.hasError('required') && name.touched"
class="alert alert-danger">Client ID is required</div>
<div *ngIf="name.hasError('npiNAN')"
class="alert alert-danger">NPI must be a number</div>
</div>
<div class="form-group" style="float: left; padding-left: 10px;">
<label for="npi">NPI:</label>
<input placeholder="0123456789" maxlength="10" id="npi" type="text" class="form-control" [ngFormControl]="clientForm.controls['npi']">
<div *ngIf="npi.hasError('required') && npi.touched"
class="alert alert-danger">NPI is required</div>
<div *ngIf="npi.hasError('npiNAN') && npi.touched"
class="alert alert-danger">NPI must be a number</div>
<div *ngIf="npi.hasError('minlength') && npi.touched"
class="alert alert-danger">NPI must be 10 characters</div>
</div>
<div style="float: left; margin: 25px 0 0 10px;">
<button type="submit" class="btn btn-default" [disabled]="!clientForm.valid">Add</button>
</div>
<br style="clear:both;" />
<div *ngIf="clientForm.hasError('npiNameDupe')"
class="alert alert-danger">NPI & Name Combo Already Exist</div>
</form>
</div>Svar #1
Eftersom getClients() är en observable, skulle du behöva sätta längden inne i subscribe-callbacken.
var clis: Client[];
var length = 0;
this._clientService.getClients().subscribe(clients => {
clis = clients;
length = clis.length;
});
Detta säkerställer att längden sätts korrekt när data returneras till din prenumeration.
När det gäller VARFÖR du får felet från första början har du inte initialiserat din array. Du skulle faktiskt behöva ange ett standardvärde eftersom den för närvarande är odefinierad, vilket orsakar ett fel när du försöker kontrollera längden.
var clis: Client[] = [];
Svar #2
Jag tror att du försöker implementera en asynkron validator. Du bör istället använda attributet asyncValidator på validator:
_fb.group({
'name': ['', Validators.compose([Validators.required])],
'npi': ['', Validators.compose([Validators.required, (...)])]
}, { asyncValidator: this.npiNameDupValidator.bind(this) });
Jag skulle omstrukturera din validator på det här sättet:
npiNameDupValidator(group: ControlGroup) {
return new Promise((resolve, reject) => {
let name = group.controls['name'];
let npi = group.controls['npi'];
this._clientService.getClients().subscribe(clients => {
var clis = clients;
var length = clis.length;
var found = (...); // your processing here
if (found) {
resolve({ npiNameDupe: true });
} else {
resolve(null);
}
});
}
