Search code examples
javascriptrecursiones6-promiseaxios

How to use recursion within a ES6 promise?


I want to check if a post with a newly set id already exists using an axios get request. (I am doing this on the front-end because I don't control the back-end)

However I am not sure how to combine the recursion I want for when a posts with that id already exists and the promise it is in.

This is what I got so far:

import axios from 'axios';
import uuidv4 from 'uuid/v4';

export function newPost(post) {
  return (dispatch) => {
    getUniqueId.then((id) => {
      // post new post with unique id
      // dispatch({ type: NEW_POST_FULFILLED, payload: err });
    }).catch((err) => {
      dispatch({ type: NEW_POST_FAILED, payload: err });
    })
  }
}

const getUniqueId = new Promise((resolve, reject) => {
  checkUniqueId(resolve, reject, uuidv4())
});

const checkUniqueId = (resolve, reject, id) => {
  axios
    .get(`${api}/posts/${id}`, { headers })
    .then((resp) => checkUniqueId(resolve, reject, uuidv4()))
    .catch((err) => {
      if(err.response.status === 500) {
        resolve(id);
      } else {
        reject(err);
      }
    });
}

Solution

  • A few issues:

    • getUniqueId should be a function, since you would want to get a new id every time newPost is called.

    • You should not use the promise constructor antipattern: don't create a new promise, but instead just return the promise itself, or throw when you need to reject.

    Here is the corrected code:

    export function newPost(post) {
        return (dispatch) => {
            // Call as function!
            getUniqueId().then((id) => {
                // post new post with unique id
                // dispatch({ type: NEW_POST_FULFILLED, payload: err });
            }).catch((err) => {
                dispatch({ type: NEW_POST_FAILED, payload: err });
            })
        }
    }
    
    // Define as function, and just return the promise from `checkUniqueId`
    const getUniqueId = _ => checkUniqueId(uuidv4());
    
    const checkUniqueId = (id) => {
        // return the promise!
        return axios
            .get(`${api}/posts/${id}`, { headers })
            .then((resp) => checkUniqueId(uuidv4()))
            .catch((err) => {
                if (err.response.status === 500) {
                    return id;
                } else {
                    throw err; // throw the error to cascade it through the chain
                }
            });
    }