1
votes

I have a project using socket.io to make calls to the server for data. This part works completely, but it uses a callback function and has no observable. So, my problem is twofold, and I don't know where to start.

I am trying to make a custom async validator, I have seen it done with Obervables, so I thought the first set is to convert my socket call to an observable.

Validator.ts

export class MyValidators {

 static rules(socket: WebSocketService) {
    return (control: AbstractControl): Observable<ValidationErrors | null> => {
      const val: string = control.value;

      const pwdRules: Observable<RuleInterface> = new Observable(observer => {
        socket.getParms((resp: SocketResponse<RuleInterface[]>) => {
          observer.next(resp.records[0]);
        });
      });

      return pwdRules.pipe(
        map(rule => val.length < rule.max_len ? null : {tooBig: true} )
      )
  }
}

So I convert my socket call to an Observable and they use pipe and map to return the null or error object.

My component FormGroup looks like this:

constructor(
    private fb: FormBuilder,
    private socket: WebSocketService
  ) { }
....

ngOnInit {
this.reset2Form = this.fb.group({
      val1: ['', [Validators.required, MyValidators .rules(this.socket)]],
      val2: ['', [Validators.required]]
    });

}

When I print out the val1 errors I get this.

{ 
   "_isScalar": false, 
    "source": { "_isScalar": false }, "operator": {} 
}

I can see form the console that the socket call never got called.

My question is what am I doing wrong? Is it the way I set up the observable? Or how I use the pipe?

1

1 Answers

0
votes

The FormBuilder.group method signature looks like:

group(controlsConfig: { [key: string]: any; }, options: AbstractControlOptions | { [key: string]: any; } = null): FormGroup

So the options is AbstractControlOptions which is define as:

Configuration options object for the FormGroup. The object can have two shapes:

1) AbstractControlOptions object (preferred), which consists of:

validators: A synchronous validator function, or an array of validator functions

asyncValidators: A single async validator or array of async validator functions

updateOn: The event upon which the control should be updated (options: 'change' | 'blur' | submit')

So instead of

ngOnInit {
    this.reset2Form = this.fb.group({
        val1: ['', [Validators.required, MyValidators.rules(this.socket)]],
        val2: ['', [Validators.required]]
    });
}

You should write:

ngOnInit {
    this.reset2Form = this.fb.group({
        val1: ['', [Validators.required], [MyValidators.rules(this.socket)]],
        val2: ['', [Validators.required]]
    });
}