colinbate / redux-form-submit-saga

Handles redux-form submissions using redux-saga
MIT License
61 stars 12 forks source link

How should I fire redux-form STOP_SUBMIT action ? #3

Closed rcalabro closed 7 years ago

rcalabro commented 7 years ago

Hi,

I trying this lib and it is working just fine, except for this issue.

After my saga runs, STOP_SUBMIT is not dispatched by the form.

This is my saga:

function* authSaga(action) {
  yield put(auth.request());
  const { data, error } = yield call(token, action.payload);
  if (data) {
    yield put(auth.success(data));
  } else {
    yield put(auth.failure(error));
  }
}

export function* watchAuth() {
  yield* takeLatest(actions.SIGNIN_SUBMIT, authSaga);
}

and this is my form:

import React, { Component, PropTypes } from 'react';
import { Field, reduxForm } from 'redux-form';
import { onSubmitActions } from 'redux-form-submit-saga';
import FormGroup from 'react-bootstrap/lib/FormGroup';
import FormControl from 'react-bootstrap/lib/FormControl';
import HelpBlock from 'react-bootstrap/lib/HelpBlock';
import Button from 'react-bootstrap/lib/Button';

import styles from '../Signin.less'; // eslint-disable-line

class SigninForm extends Component {

  getValidationState = ({ touched, error, warning }) => {
    if (touched && error) {
      return { validationState: 'error' };
    } else if (touched && warning) {
      return { validationState: 'warning' };
    }
    return undefined;
  }

  renderField = ({ input, label, type, meta: { touched, error, warning } }) => (
    <FormGroup
      className={styles['loginbox-textbox']}
      {...this.getValidationState({ touched, error, warning })}
    >
      <FormControl
        componentClass="input" type={type} placeholder={label}
        className={styles['form-control']}
        {...input}
      />
      {touched && ((error && <HelpBlock>{error}</HelpBlock>) || (warning && <HelpBlock>{warning}</HelpBlock>))}
    </FormGroup>
  )

  render() {
    const { handleSubmit, submitting, error, touched } = this.props;

    return (
      <form onSubmit={handleSubmit}>
        <Field name="username" type="text" label="Email" component={this.renderField} />
        <Field name="password" type="password" label="Password" component={this.renderField} />
        {touched && error && <span>{error}</span>}
        <div className={styles['loginbox-forgot']}>
          <a href>
            Forgot Password?
          </a>
        </div>
        <div className={styles['loginbox-submit']}>
          <Button type="submit" disabled={submitting} bsStyle="primary" block>
            Sign in
          </Button>
        </div>
      </form>
    );
  }

}

SigninForm.propTypes = {
  submitting: PropTypes.bool.isRequired,
  handleSubmit: PropTypes.func.isRequired,
  error: PropTypes.string,
  touched: PropTypes.bool
};

const validate = values => {
  const errors = {};
  if (!values.username) {
    errors.username = 'Required';
  }
  if (!values.password) {
    errors.password = 'Required';
  }
  return errors;
};

// eslint-disable-next-line
SigninForm = reduxForm({
  form: 'signinForm',
  onSubmit: onSubmitActions('SIGNIN'),
  validate
})(SigninForm);

export default SigninForm;

Am I using it wrong?

Thanks

rcalabro commented 7 years ago

Solved using redux-form action creators in my authSaga

import { put, call } from 'redux-saga/effects';
import { takeLatest } from 'redux-saga';
import { token } from 'services/api/auth';
import { stopSubmit, setSubmitSucceeded, setSubmitFailed } from 'redux-form/lib/actions';
import * as actions from './actions';

const { auth } = actions.sagaActions;

function* authSaga(action) {
  yield put(auth.request());
  const { data, error } = yield call(token, action.payload);
  if (data) {
    yield put(stopSubmit('signinForm'));
    yield put(auth.success(data));
    yield put(setSubmitSucceeded('signinForm'));
  } else {
    yield put(stopSubmit('signinForm', { _error: error.message }));
    yield put(auth.failure(error));
    yield put(setSubmitFailed('signinForm'));
  }
}

export function* watchAuth() {
  yield* takeLatest(actions.SIGNIN_SUBMIT, authSaga);
}

export default {
  watchAuth
};