1

I am using react redux form to send form data to server. The form will correctly show failed if I return a promise that fails but not if I throw or use async/await with throw. I still have to return a rejected promise. Not sure what I am missing here or if that's the way of things.

Works:

export const myRequest = (data) => {
   return new Promise((resolve, reject) => {
    reject('Login failed!')
   })
}

Does not (as well as the async/await variants):

export const myRequest = (data) => {
   throw new Error('Login failed')
}

What I have to do:

export const myRequest = (data) => {
  try {
    ...
  } catch (err) {
     return new Promise((resolve, reject) => {
       reject(...)
   })
  }  
}

Here's some async code I am working with. I have to wrap the error message in a promise in order for the form to get the message, I am not sure why it doesn't get the message the same way when I throw.

const myRequest = async ( data) => {
  try {
    let response = await fetch(url, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(data)
    })

    if (!response.ok) {
      throw new Error(response.statusText)
    }
    return await response.json()
  } catch (err) {
    // Not working - no error message makes it - though it gets that it's an error
    throw new Error(err) // or new Error(err.message) or new Error('foo')

    // Works
    // return new Promise((resolve, reject) => {
    //   reject(err.message)
    // })
  }
}

My React Redux Form:

import myRequest from '...'

handleSubmit (values) {
  const { dispatch } = this.props
  dispatch(actions.submit('subscribe', myRequest(values)))
}

render () {
   const { valid, pending, submitted, submitFailed } = this.props.form
  return (
    <Form model='subscribe' onSubmit={(values) => this.handleSubmit(values)}>
    { !valid && submitFailed ? <Alert>          
      <Errors
        model='subscribe' // Form name as found in reducer
      /> : null
    }
    </Form>
  }
}
cyberwombat
  • 38,105
  • 35
  • 175
  • 251

3 Answers3

1

React-Redux-Form creator here. This has just been fixed and will be out in the next release: https://github.com/davidkpiano/react-redux-form/issues/877

David Khourshid
  • 4,918
  • 1
  • 11
  • 10
0

I think redux form is expecting a promised to be returned. Luckily, all async functions always return promises. I bet if you changed your code to:

 export const myRequest = async (data) => {
   throw new Error('Login failed')
 }

you'd get the error gong to the right place.

Zeke Nierenberg
  • 2,216
  • 1
  • 19
  • 30
  • Unfortunately no. I mean it does recognize that it failed but the "Login failed" message isn't returned - or at least not in a way that I figured out. – cyberwombat Jul 08 '17 at 18:44
0

Using an async function is the correct thing to do here. However, to get the equivalent of reject(err.message), you would need to do throw err.message. But you should never throw strings, better throw new Error(err.message). Or just throw err. Or just don't catch anything at all and let it bubble.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • I have tried these variations as well with no success. `err`, `err.message` or strings do not seem to make it to react redux form. It does mark the form as invalid but no message. – cyberwombat Jul 08 '17 at 19:02
  • Throwing it is exactly the same thing as rejecting it. Can you show us the part where `myRequest` called, and the error is handled? – Bergi Jul 08 '17 at 20:09
  • Updated with React code. The Error component is the one that prints out the error for the whole form as found in the rejected promise. Right now the Error component shows correctly but no message so something in RRF is differentiating between the methods tried. – cyberwombat Jul 08 '17 at 21:03