Paul Ness
Paul Ness

Reputation: 113

Add multiple callback responses to array

I have this multiple function called checkForURLS that calls another two functions that return callbacks, how can I add to the array once both callbacks have returned and then return the array as a callback? I'm working with pure JavaScript.

function checkForURLs(uniqueURL, customURL, callback) {
    var errors = [];

    checkForUniqueURL(uniqueURL, function(UniqueURLCallback) {
        if (UniqueURLCallback===true) {
            errors.push("This unique URL is already taken, please try another.");
        }
    });

    if (customURL.length>0) {
        checkForCustomURL(customURL, function(customURLCallback) {
            if (customURLCallback===true) {
                errors.push("This custom URL is already taken, please try another.");
            }
        });
    }

    if (errors.length>0) {
        return callback(errors);
    } else {
        return callback(false);
    }
}

Upvotes: 1

Views: 436

Answers (3)

guest271314
guest271314

Reputation: 1

You can use Promise constructor new Promise(function), Promise.all() to perform task when checkForUniqueURL and checkForCustomURL callbacks have been called.

function callback(value) {
  return value
}

function checkForUniqueURL(url, callback) {
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      resolve(callback(true))
    }, Math.random() * 1500)
  })
}

function checkForCustomURL(url, callback) {
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      resolve(callback(true))
    }, Math.random() * 1500)
  })
}

function checkForURLs(uniqueURL, customURL, callback) {
  var errors = [];

  return Promise.all([
    new Promise(function(resolve, reject) {
      checkForUniqueURL(uniqueURL, function(UniqueURLCallback) {
        if (UniqueURLCallback === true) {
          errors.push("This unique URL is already taken, please try another.");
        } 
        resolve()
      })
    })
  , new Promise(function(resolve, reject) {
      if (customURL.length > 0) {
        checkForCustomURL(customURL, function(customURLCallback) {
          if (customURLCallback === true) {
            errors.push("This custom URL is already taken, please try another.");
          }
          resolve()
        });
      }
    })
  ])
  .then(function() {
    console.log(errors);
    if (errors.length > 0) {
        return Promise.resolve(callback(errors));
    } else {
        return Promise.reject(callback(new Error("false")));
    }
  })
}

checkForURLs("abc", "def", callback)
  .then(function(errs) {
    console.log(errs);
  })
  .catch(function(err) {
    console.log("err:", err.message)
  })

Upvotes: 1

Charlie Martin
Charlie Martin

Reputation: 8406

This will work IFF your checkForUniqueURL and checkForCustomURL functions are synchronous. Here is an example of it working with synchronous functions...

https://jsfiddle.net/ojh5b1f8/

However, I'm going to assume, since its not working, that your functions are asynchronous. Here is an example of it not working with asynchronous functions...

https://jsfiddle.net/uzjbyrt7/

It doesn't work, because the checkForURLs function returns before the callbacks are fired. The best solution in this case, is Promises. However, you will likely need to use a library to get promise support, since they are not yet implemented in all browsers. I recommend bluebird.js. Here is an example of it working with asynchronous functions and promises...

https://jsfiddle.net/ynxcu7t6/

Upvotes: 0

user7028020
user7028020

Reputation:

If all functions you use are synchronous and are implemented similar to the following, you code works perfectly well:

function checkForURLs(uniqueURL, customURL, callback) {
    var errors = [];

    checkForUniqueURL(uniqueURL, function(UniqueURLCallback) {
        if (UniqueURLCallback===true) {
            errors.push("This unique URL is already taken, please try another.");
        }
    });

    if (customURL.length>0) {
        checkForCustomURL(customURL, function(customURLCallback) {
            if (customURLCallback===true) {
                errors.push("This custom URL is already taken, please try another.");
            }
        });
    }

    if (errors.length>0) {
        return callback(errors);
    } else {
        return callback(false);
    }
}

// Just test-implement those two functions:
function checkForUniqueURL(url, callback) { callback(true); }
function checkForCustomURL(url, callback) { callback(true); }


errors = checkForURLs("test", "test2", function(errors) {
  console.log(errors);
  return "I have got some errors!";
});

console.log(errors);

If indeed your code has asynchronous parts, you would need to "wait" with the return callback() until those are finished. Maybe by wrapping them in another callback?

Upvotes: 0

Related Questions