admin管理员组

文章数量:1435534

I've got a sign up form and I want to check that if the username is already taken or not. To achieve this I'm using promises now. My sign up ponent looks like this:

import { Component, OnInit } from '@angular/core';
import { FormControl, FormBuilder, FormGroup, Validators } from '@angular/forms';
import { UserService } from '../shared/user.service'

@Component({
  selector: 'app-auth',
  providers: [],
  templateUrl: './authponent.html',
  styleUrls: ['./authponent.css']
})

export class AuthComponent implements OnInit {

  // Tabs for log in or sign up
  tab = 'signup';

  // Sign up form
  signUpForm: FormGroup;

  // Log in form
  logInForm: FormGroup;

  constructor(private formBuilder: FormBuilder, private ussr: UserService) {
     this.signUpForm = this.formBuilder.group({
       'username': [null, [
         Validators.required, Validators.minLength(4), Validators.maxLength(12), this.ussr.getUserNameFromServer
       ]], 
       'email': '', 
       'password': '' });
    this.logInForm = this.formBuilder.group({ 'username': '', 'password': '' });
  }

  ngOnInit() {
  }

  activeTab(tab: string) {
    this.tab = tab;
  }

  signUpSubmit(value: any) {
    console.log(value);
  }

}

And the UserService:

import { Injectable } from '@angular/core';
import { Http, Response, Headers, RequestOptions  } from '@angular/http';
import { FormControl } from '@angular/forms';
import 'rxjs/add/operator/map';

@Injectable()
export class UserService {

    constructor (private http: Http) {}

    private extractData (res: Response) {
        let body = res.json();
        return body || { };
    }

    getUserNameFromServer = (c: FormControl) => {

        return new Promise (
             (resolve, reject) => {
                 this.http.get('')
                 .map(this.extractData)
                 .subscribe(
                     (res: any) => {
                         if (c.value == res.username) {
                             console.log('taken')
                             resolve({'usernameTaken': true})
                         } else {
                             console.log('is not taken')
                             resolve(null)
                         }
                     },
                     err => { console.log(err) }
                 )   
             }
         );

    }

}

I already read some blog posts about this topic, and I also checked two SO questions (1, 2), but I can't get it to work. The service successfully got the server's answer, but when I call it inside the ponent's validator, the form is going to be invalid every time.

In the examples above, they just call it in the validator section, and I guess the ng2 do the rest of the work in the background, or am I wrong? How is the validator got the promise's value?

I've got a sign up form and I want to check that if the username is already taken or not. To achieve this I'm using promises now. My sign up ponent looks like this:

import { Component, OnInit } from '@angular/core';
import { FormControl, FormBuilder, FormGroup, Validators } from '@angular/forms';
import { UserService } from '../shared/user.service'

@Component({
  selector: 'app-auth',
  providers: [],
  templateUrl: './auth.ponent.html',
  styleUrls: ['./auth.ponent.css']
})

export class AuthComponent implements OnInit {

  // Tabs for log in or sign up
  tab = 'signup';

  // Sign up form
  signUpForm: FormGroup;

  // Log in form
  logInForm: FormGroup;

  constructor(private formBuilder: FormBuilder, private ussr: UserService) {
     this.signUpForm = this.formBuilder.group({
       'username': [null, [
         Validators.required, Validators.minLength(4), Validators.maxLength(12), this.ussr.getUserNameFromServer
       ]], 
       'email': '', 
       'password': '' });
    this.logInForm = this.formBuilder.group({ 'username': '', 'password': '' });
  }

  ngOnInit() {
  }

  activeTab(tab: string) {
    this.tab = tab;
  }

  signUpSubmit(value: any) {
    console.log(value);
  }

}

And the UserService:

import { Injectable } from '@angular/core';
import { Http, Response, Headers, RequestOptions  } from '@angular/http';
import { FormControl } from '@angular/forms';
import 'rxjs/add/operator/map';

@Injectable()
export class UserService {

    constructor (private http: Http) {}

    private extractData (res: Response) {
        let body = res.json();
        return body || { };
    }

    getUserNameFromServer = (c: FormControl) => {

        return new Promise (
             (resolve, reject) => {
                 this.http.get('https://jsonplaceholder.typicode./users/1')
                 .map(this.extractData)
                 .subscribe(
                     (res: any) => {
                         if (c.value == res.username) {
                             console.log('taken')
                             resolve({'usernameTaken': true})
                         } else {
                             console.log('is not taken')
                             resolve(null)
                         }
                     },
                     err => { console.log(err) }
                 )   
             }
         );

    }

}

I already read some blog posts about this topic, and I also checked two SO questions (1, 2), but I can't get it to work. The service successfully got the server's answer, but when I call it inside the ponent's validator, the form is going to be invalid every time.

In the examples above, they just call it in the validator section, and I guess the ng2 do the rest of the work in the background, or am I wrong? How is the validator got the promise's value?

Share Improve this question edited May 23, 2017 at 10:31 CommunityBot 11 silver badge asked Jan 2, 2017 at 23:12 pkovzzpkovzz 3642 gold badges5 silver badges14 bronze badges 5
  • not promises are thrown by the observables, the problem is local. – Roman C Commented Jan 2, 2017 at 23:41
  • What do you mean? – pkovzz Commented Jan 3, 2017 at 6:31
  • You should consider rephrasing the question to something like: Angular 2.3.1 async custom validator promise doesn't resolve – nthaxis Commented Jan 13, 2017 at 19:34
  • Thanks, I edited! – pkovzz Commented Jan 14, 2017 at 21:03
  • I have spent almost a day for async validations and return status issues, and Voila, your code worked like a charm! Thanks a lot. – Fawkes Commented Aug 29, 2017 at 10:30
Add a ment  | 

1 Answer 1

Reset to default 9

The problem was that I insert the async custom validator into the sync validator section. Which means the 2nd param is for the sync validators, the 3rd one for the async ones.

This works now:

'username': [null,
         [ Validators.required, Validators.minLength(4), Validators.maxLength(12) ],
         [ this.ussr.getUserNameFromServer ]
  ],

本文标签: javascriptAngular 231 async custom validator promise doesn39t resolveStack Overflow