Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom validator for uniqueness in Angular2

I have an Angular2 form field. I want to require that the entered value doesn't already exist. My component receives the array of existing values via an @Input parameter. I have a custom validator function in my component, codeUnique(), but when it's executed it has no access to instance members. "this" returns either FormControl or undefined. My validator function has been sucked into outer space, stripped of it's context and instance variables. How can I get my list of existing values into my validator? Could I put them in a global scope, horror?

import { Component, Input, Output, EventEmitter } from '@angular/core';
import { NG_VALIDATORS, FormControl, FormBuilder, FormGroup, Validators, AbstractControl } from '@angular/forms';

import { ReferringAppModel } from './referringapp.model';
//import { CodeValidator } from './code-validator';

@Component({
    selector: 'add-client-form',
    templateUrl: 'src/home/add-client-form.component.html'
})
export class AddClientFormComponent {
    myForm: FormGroup;
    code: AbstractControl;
    name: AbstractControl;

    constructor(fb: FormBuilder) {
        this.myForm = fb.group({
            'code': ['', this.codeUnique],
            'name': ['', Validators.required]
        });
        this.code = this.myForm.controls['code'];
        this.name = this.myForm.controls['name'];
    }
    @Input() referringApps: ReferringAppModel[];

    ngOnInit() {
    }
    onSubmit(form: any): void {
        console.log("submitted")
    };

    codeUnique(c: FormControl) {
        try {
            // Blows up. 
            return !this.referringApps.find(appInApps => appInApps.Code == c.value) ? null : {
                //return false ? null : { // WORKS
                validateEmail: {
                    valid: false
                }
            };
        } catch (ex) {
            console.log(ex);
        }
    }
}


TypeError: Cannot read property 'referringApps' of undefined
    at AddClientFormComponent.codeUnique (http://localhost/HubHacienda/dist/bundle.js:50071:26)
    at http://localhost/HubHacienda/dist/bundle.js:43538:54
    at Array.map (native)
    at _executeValidators (http://localhost/HubHacienda/dist/bundle.js:43538:28)
    at FormControl.Validators.compose [as validator] (http://localhost/HubHacienda/dist/bundle.js:43518:38)
    at FormControl.AbstractControl._runValidator (http://localhost/HubHacienda/dist/bundle.js:45083:54)
    at FormControl.AbstractControl.updateValueAndValidity (http://localhost/HubHacienda/dist/bundle.js:45061:38)
    at FormControl.setValue (http://localhost/HubHacienda/dist/bundle.js:45327:19)
    at DefaultValueAccessor.onChange (http://localhost/HubHacienda/dist/bundle.js:44287:22)
    at DebugAppView._View_AddClientFormComponent0._handle_input_12_0 (AddClientFormComponent.ngfactory.js:493:47)
    at DebugAppView.eventHandler (http://localhost/HubHacienda/dist/bundle.js:35576:29)
    at COMPONENT_REGEX (http://localhost/HubHacienda/dist/bundle.js:38521:41)
    at http://localhost/HubHacienda/dist/bundle.js:38634:116
    at ZoneDelegate.invoke (http://localhost/HubHacienda/dist/bundle.js:6875:29)
    at Object.onInvoke (http://localhost/HubHacienda/dist/bundle.js:32132:42)
    at ZoneDelegate.invoke (http://localhost/HubHacienda/dist/bundle.js:6874:35)
    at Zone.runGuarded (http://localhost/HubHacienda/dist/bundle.js:6782:48)
    at NgZoneImpl.runInnerGuarded (http://localhost/HubHacienda/dist/bundle.js:32161:83)
    at NgZone.runGuarded (http://localhost/HubHacienda/dist/bundle.js:32393:78)
    at HTMLInputElement.outsideHandler (http://localhost/HubHacienda/dist/bundle.js:38634:84)
    at ZoneDelegate.invokeTask (http://localhost/HubHacienda/dist/bundle.js:6908:38)
    at Zone.runTask (http://localhost/HubHacienda/dist/bundle.js:6808:48)
    at HTMLInputElement.ZoneTask.ZoneTask.cancelFn.invoke (http://localhost/HubHacienda/dist/bundle.js:6976:34)
like image 518
bbsimonbb Avatar asked Oct 20 '16 09:10

bbsimonbb


People also ask

What must be returned from a custom validator function?

The validator function needs to return null if no errors were found in the field value, meaning that the value is valid.

What methods should you implement for your custom validator?

Implementing the Validator Interface A Validator implementation must contain a constructor, a set of accessor methods for any attributes on the tag, and a validate method, which overrides the validate method of the Validator interface.

What is custom validator in Angular?

A validator in Angular is a function which returns null if a control is valid or an error object if it's invalid. For model-driven forms we create custom validation functions and pass them into the FormControl constructor.


1 Answers

simple: when assigning the validator you bind the this argument of your class to it, like so: 'code : ['', this.codeUnique.bind(this)]

like image 89
LRN Avatar answered Sep 24 '22 23:09

LRN