How can I make a discount for submitting an action and also return a promise?

Here is my function in songAction.js

export function createSong(title, url, token) {

    axios.defaults.headers.common['Authorization'] = token

    return function (dispatch) {
        axios.post('http://localhost:8080/api/song/create', {
            title,
            link: url

        })
        .then((response) => {
            console.log('the response was', response)
            if(response.data.success){
                dispatch({type: "CREATE_SONG_FULFILLED", payload: response.data.song})
            } else {
                dispatch({type: "CREATE_SONG_REJECTED", payload: response.data})

            }
        })
        .catch((err) => {
            dispatch({type: "CREATE_SONG_REJECTED", payload: err})
        })
    }
}

      

I want to be able to return the promise after dispatch, so I can use a function like this inside the component -

 createSong(title, url, token)
   .then((result) =>{
        // do stuff with result 
     })

      

I know I can pass a callback to make this async work .. but I want to use ES6 promises features. And I am a little confused how I can do this.

+3


source to share


3 answers


If you want to go through full ES6 you must use the syntax async/await

. This removes the need to deal with promises at all.

export function createSong (title, url, token) {
  axios.defaults.headers.common['Authorization'] = token
  return async (dispatch) => {
    try {
      const response = await axios.post('http://localhost:8080/api/song/create', {
        title,
        link: url
      })
      console.log('the response was', response)
      if (response.data.success) {
        dispatch({type: 'CREATE_SONG_FULFILLED', payload: response.data.song})
      } else {
        dispatch({type: 'CREATE_SONG_REJECTED', payload: response.data})
      }
    } catch (err) {
      dispatch({type: 'CREATE_SONG_REJECTED', payload: err})
    }
  }
}

      

The anonymous function returned createSong

is marked with a new keyword async

. This means that the anonymous function will now return an implicit promise.



The keyword async

also allows you to use await

functions in the body so that you can await

call asynchronously axios.post

, and therefore treat it as if it were a synchronous call.

Another advantage is that you can revert to using regular blocks try / catch

. They actually allow and deny the implicit promise behind the scenes, but they operate in the usual way.

Since the anonymous function actually returns a Promise, above the call chain, wherever you call the function createSong(...)

, you can also use the syntax async / await

... and so on. No more callbacks and more explicit promise handling.

0


source


First of all, you need to return the challenge axios

.

...
return function (dispatch) {
  return axios.post('http://localhost:8080/api/song/create', {
    title,
    link: url
  })
...

      

Your function createSong

returns another function (so this is a curric function).



Hence,

createSong(title, url, token)(dispatch)
.then(()=>{
  // something
})

      

looks pretty correct.

0


source


I think this is not a very "React" way of using the return values โ€‹โ€‹of dispatched actions.

There is a better way to deal with tricky situations like Redux Saga , for example here .

Although, in the past I've used return values โ€‹โ€‹by sending actions like this:

export const updatePage = (id, batch) => {
  return dispatch => {
    dispatch({
      type: 'UPDATE_PAGE',
      payload: {
        id
      }
    })

    // Make an API call
    return requestUpdatePages(
      id, batch
    ).then(data => {
      // When API call is successful
      return dispatch({
        type: 'UPDATE_PAGE_SUCCESS',
        payload: {
          id,
          data
      })
    })
    .catch(error => {
      // When API call fails
      return dispatch({
        type: 'UPDATE_PAGE_FAIL',
        payload: {
          error,
          id
        },
        error: true
      })
    })
  }
}

// After dispatch is bound to action creators
// you can use it like this

handleClick(id) {
  const { updatePage } = this.props
  updatePage(id).then(action => {
    if(action.type === 'UPDATE_PAGE_SUCCESS') {
      console.log('Whee, page has been updated!', action.payload.data)
    } else {
      console.error('Something went wrong :-( ', action.payload.error)
    }
  })
}

      

0


source







All Articles