cyberwombat
cyberwombat

Reputation: 40074

Rejecting react redux form with async/throw instead of promise

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>
  }
}

Upvotes: 1

Views: 1334

Answers (3)

David Khourshid
David Khourshid

Reputation: 5203

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

Upvotes: 1

Bergi
Bergi

Reputation: 664246

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.

Upvotes: 0

Zeke Nierenberg
Zeke Nierenberg

Reputation: 2206

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.

Upvotes: 0

Related Questions