Ad

Debounce Async/await And Update Component State

- 1 answer

I have question about debounce async function. Why my response is undefined? validatePrice is ajax call and I receive response from server and return it (it is defined for sure).

I would like to make ajax call after user stops writing and update state after I get reponse. Am I doing it right way?

handleTargetPriceDayChange = ({ target }) => {
        const { value } = target;

        this.setState(state => ({
            selected: {
                ...state.selected,
                Price: {
                    ...state.selected.Price,
                    Day: parseInt(value)
                }
            }
        }), () => this.doPriceValidation());
    }

doPriceValidation = debounce(async () => {
        const response = await this.props.validatePrice(this.state.selected);
        console.log(response);
        //this.setState({ selected: res.TOE });
    }, 400);

actions.js

   export function validatePrice(product) {
        const actionUrl = new Localization().getURL(baseUrl, 'ValidateTargetPrice');
        return function (dispatch) {
            dispatch({ type: types.VALIDATE_TARGET_PRICE_REQUEST });
          dispatch(showLoader());
            return axios.post(actionUrl, { argModel: product }, { headers })
                .then((res) => {
                    dispatch({ type: types.VALIDATE_TARGET_PRICE_REQUEST_FULFILLED, payload: res.data });
                    console.log(res.data); // here response is OK (defined)
                    return res;
                })
                .catch((err) => {
                    dispatch({ type: types.VALIDATE_TARGET_PRICE_REQUEST_REJECTED, payload: err.message });
                })
                .then((res) => {
                  dispatch(hideLoader());
                 return res.data;
        });
        };
    }
Ad

Answer

Please find below the working code with lodashdebounce function.

Also here is the codesandbox link to play with.

Some changes:-

1) I have defined validatePrice in same component instead of taking from prop.

2) Defined the debounce function in componentDidMount.

import React from "react";
import ReactDOM from "react-dom";
import _ from "lodash";

import "./styles.css";

class App extends React.Component {
  state = {
    selected: { Price: 10 }
  };
  componentDidMount() {
    this.search = _.debounce(async () => {
      const response = await this.validatePrice(this.state.selected);
      console.log(response);
    }, 2000);
  }
  handleTargetPriceDayChange = ({ target }) => {
    const { value } = target;
    console.log(value);
    this.setState(
      state => ({
        selected: {
          ...state.selected,
          Price: {
            ...state.selected.Price,
            Day: parseInt(value)
          }
        }
      }),
      () => this.doPriceValidation()
    );
  };

  doPriceValidation = () => {
    this.search();
  };
  validatePrice = selected => {
    return new Promise(resolve => resolve(`response sent ${selected}`));
  };
  render() {
    return (
      <div className="App">
        <input type="text" onChange={this.handleTargetPriceDayChange} />
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Hope that helps!!!

Ad
source: stackoverflow.com
Ad