1

I want to assign a promise to a variable in the following way:

const createSingleUser = function createSingleUser(userData) {
  return new Promise((resolve, reject) => {
    new User(userData)
    .save()
    .then((user) => {
      resolve(user, 'user');
    })
    .catch((error) => {
      reject(error);
    });
  });
};

let createUsers;
if (users instanceof Array) {
  // If we have an array, we're batch creating users
  createUsers = new User().createBatchUsers(users); // returns promise
} else {
  // If we have a single object, we're only creating one user
  createUsers = new User().createSingleUser(users); // returns promise
}
createSingleUser(users)
createUser
.then((result) => {
.....

However this does not work due to timing issues. Is there another way to make such a construct without having to write the promise chain twice?

Edit As @torazaburo mentions, If you create a promise, it will start running. You can assign it to a variable, but the variable will represent the running promise. This is the problem I'm facing. This is the case since createSingleUser is a (Promise) object and not a function.

adnan
  • 1,385
  • 2
  • 17
  • 31
  • 3
    Hi, I do not get where are you writing the promise twice. Why are you creating `new User().createSingleUser(users)` after the `IF` statement before the `createUser.then((result) => {...` sentence? – Andrea Dec 20 '16 at 08:59
  • What "*does not work due to timing issues*"? – Bergi Dec 20 '16 at 09:06
  • 1
    If you create a promise, it will start running. You can assign it to a variable, but the variable will represent the running promise. That does not seem to be what you want. What you probably want to do is to store a **function** which creates the promise into a variable, then, when you are ready to run it, get the promise by invoking the promise--in the above, it would be `createUser().then(...`. –  Dec 20 '16 at 09:15
  • `createUser` is undefined. Please, provide real code that can explain what's going on. – Estus Flask Dec 20 '16 at 09:15
  • @torazaburo I was having a hard time explaining the problem but yes that is exactly the problem. Let me check and try this. – adnan Dec 20 '16 at 09:23
  • Now you've got `createSingleUser`, `createUsers` and `createUser` variables in your code. What do you actually want? There doesn't seem to be any problem with starting the tasks right from inside that if-statement, or is there? Just don't call both the `createSingleUser(users)` function and the `new User().createSingleUser(users);` method. – Bergi Dec 20 '16 at 09:28
  • 1
    Btw, avoid the [`Promise` constructor antipattern](http://stackoverflow.com/q/23803743/1048572?What-is-the-promise-construction-antipattern-and-how-to-avoid-it)! – Bergi Dec 20 '16 at 09:29
  • @bergi If the input is an array, I need to create a batch of users, if the input is an object, I need to create a single user. I can start the task from inside the if statement, but that would lead to code duplication and two different catch statements. – adnan Dec 20 '16 at 09:30
  • @Bergi, I don't think this is a promise antipattern, creating the user is async, so I need a promise there. – adnan Dec 20 '16 at 09:34
  • 1
    @adnan Yes it the antipattern, please read the linked answers carefully. You already *have* a promise there returned by the async `save` method, so you don't need another one to wrap it. The whole thing should be simplified to `function createSingleUser(userData) { return new User(userData).save(); }` – Bergi Dec 20 '16 at 09:41

2 Answers2

4

You already are writing the promise chain only once:

let createdUsers;
if (users instanceof Array) {
  createdUsers = new User().createBatchUsers(users);
} else {
  createdUsers = new User().createSingleUser(users);
}
// createSingleUser(users)
// ^^^^^^^^^^^^^^^^^^^^^^^ make sure to drop this line
createdUsers
.then((result) => {
    … // handle both cases here
})
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
1

Pretty unclear question, so here's a few answers.

You can use Promise.all(arrayOfPromises) to wait for several promises before a then().

You can put your if-else code in a function if you need to run it twice:

function createUsers(users) {
  if (users instanceof Array) {
    return new User().createBatchUsers(users);
  }
  return new User().createSingleUser(users);
}

createUsers(users)
  .then(() => createUsers(users))
  .then(...);
Kris Selbekk
  • 7,438
  • 7
  • 46
  • 73