Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to disable a button while waiting for redux to resolve?

In following example, how can I disable the button during a geolocation request? In this.props.inProgress isn't set on init, I would like to disable button when getCurrentPosition is requested and enable if RECEIVE_LOCATION is resolved. What is correct approach? Do I to use state and copy props to the GeoButton?

export function getGeolocation() {
  return dispatch => {
    if (navigator.geolocation) {
      navigator.geolocation.getCurrentPosition(function(position) {
        dispatch({
          type: 'RECEIVE_LOCATION',
          coords: {
            latitude: position.coords.latitude,
            longitude: position.coords.longitude,
            inProgress: false,
          },
        });
      });
    }
  }
}
export function geolocation(state={}, action) {
  switch (action.type) {
    case 'RECEIVE_LOCATION':
      var newState = action.coords;

      return newState;
    default:
      return state;
  }
}


class GeoButton extends React.Component {
  constructor(props) {
    super(props);
  }

  findLocation(e) {
    e.preventDefault();
    this.props.dispatch(getGeolocation());
  }
  render() {
    console.log(this.props); // on init geolocation object is empty
    var self = this;
    return (
      <div>
        <button type="button" onClick={this.findLocation} disabled={self.props.geolocation.inProgress}>Get location</button>
      </div>
    )
  }
}

export default connect(state => ({
  geolocation: state.geolocation
}))(GeoButton); // just gives it dispatch()
like image 671
luzny Avatar asked Nov 22 '15 09:11

luzny


People also ask

How do I disable a button in a script?

To disable a button using only JavaScript you need to set its disabled property to false . For example: element. disabled = true . And to enable a button we would do the opposite by setting the disabled JavaScript property to false .

How do you disable a button on click in react?

Use the disabled prop to disable a button in React, e.g. <button disabled={true}>Click</button> . You can use the prop to conditionally disable the button based on the value of an input field or another variable or to prevent multiple clicks to the button.

How do I disable a button in angular?

Button component can be enabled/disabled by giving disabled property. To disable Button component, the disabled property can be set as true .

How do you button disable and enable in angular?

You can enable or disable the ButtonGroup for Angular. By default, the component is enabled. To disable the whole group of buttons, set the disabled attribute of the ButtonGroup to true . To disable a specific button, set its own disabled attribute to true and leave the disabled attribute of the ButtonGroup undefined.


1 Answers

When doing async in redux, you often need to call dispatch twice. One synchronous, one asynchronous.

Your action should look something like this:

export function getGeolocation() {
  return dispatch => {
    dispatch({ type: 'FETCHING_LOCATION' });
    if (navigator.geolocation) {
      navigator.geolocation.getCurrentPosition((position) => {
        dispatch({
          type: 'RECEIVE_LOCATION',
          coords: {
            latitude: position.coords.latitude,
            longitude: position.coords.longitude
          }
        });
      });
    }
  };
}

And your reducer should look like this. I've tweaked the structure of the state object, to separate the app data from the ui data.

export function geolocation(state = {}, action) {
  switch (action.type) {
    case 'RECEIVE_LOCATION':
      return {
        coords: action.coords,
        inProgress: false
      };
    case 'FETCHING_LOCATION':
      return {
        coords: null,
        inProgress: true
      };
  }
  return state;
}

There's no need to have the inProgress flag set within your action creator. The reducer can derive it from the action type.

like image 174
David L. Walsh Avatar answered Sep 22 '22 10:09

David L. Walsh