3

How do I add some delays or sort of debouncing of validator which returns a promise. I'm using Antd with its Form component. My custom validator sends a request to the server whether a username is already exists in the database or not.

The docs says to return a promise, so here's what I did.

rules={[
      { required: true, message: "Please input your username!" },
      ({ getFieldValue }) => ({
        validator(rule, value) {
          return new Promise((resolve, reject) => {
            api.post("/users/check", { username: value }).then(response => {
              if (response.data.exist) {
                reject("Username already exists.");
              } else {
                resolve();
              }
            });
          });
        }
      })
    ]}

and it works perfectly but the problem is, every keystroke will send a request to the server but I think this is not good for both server and client. So what I think of, is some sort of delays like debounce or setTimeOut but none of them works.I use debounce function from lodash.

 return new Promise((resolve, reject) => {
  debounce(() => {
    api
      .post("/users/check", { username: value })
      .then(response => {
        if (response.data.exist) {
          reject("Username already exists.");
        } else {
          resolve();
        }
      });
 }, 500);

I expect that there should be a request sent to the server but I never see the request to the server.

I think I'm missing something or what. Hopefully someone can answer.

Thank you.

Ricardo Raz
  • 493
  • 1
  • 10
  • 23

1 Answers1

2

As stated in this answer

You should avoid using the debounce function provided by Lodash when dealing with promises

So you can use another library:

import React from "react";
import { Form, Input, Button } from "antd";
import debounce from "debounce-promise";

const request = debounce(() => {
  console.log("request called");
  return Promise.resolve({ data: { exist: true } });
}, 500);

const Demo = () => {
  const [form] = Form.useForm();
  const onFinish = () => {
    console.log("Submit success!");
  };

  const onFinishFailed = () => {
    console.log("Submit failed!");
  };

  return (
    <Form
      form={form}
      layout="vertical"
      onFinish={onFinish}
      onFinishFailed={onFinishFailed}
    >
      <Form.Item
        name="url"
        label="URL"
        rules={[
          ({ getFieldValue }) => ({
            validator(rule, value) {
              return new Promise((resolve, reject) => {
                request("/users/check", { username: value }).then(
                  (response) => {
                    if (response.data.exist) {
                      reject("Username already exists.");
                    } else {
                      resolve();
                    }
                  }
                );
              });
            }
          })
        ]}
      >
        <Input placeholder="input placeholder" />
      </Form.Item>
      <Form.Item>
        <Button type="primary" htmlType="submit">
          Submit
        </Button>
      </Form.Item>
    </Form>
  );
};
Andrey
  • 928
  • 1
  • 12
  • 20