0

Inside a Node controller method I have this code block that I would like to await for before continuing with the code that comes next. How can I do this?

I thought this should be done with a Promise (the only one in that controller method) and have tried the code below. But this generates the error below. What am I doing wrong?

TypeError: object is not iterable (cannot read property Symbol(Symbol.iterator))

const other = new Promise(async function () {
    updatedFields.last_login_at = newDateNow();
    if (updatedFields.isActivated) {
        updatedFields.activated_at = newDateNow();
        updatedFields.deactivated_at = null;
    } else if (updatedFields.isActivated === false) {
        updatedFields.deactivated_at = newDateNow();
        updatedFields.activated_at = null;
    }
});

await Promise.all(other);

... only when the Promise is completed, continue with the rest of the code
Zoe
  • 47
  • 6
  • 1
    "*I have this code block that I would like to `await`*" - why?! Is there anything asynchronous in there? It looks very much like synchronous code, in which case all the following code will be executed after it anyway. – Bergi Jul 03 '22 at 22:18
  • 1
    "*TypeError: object is not iterable*" - you'd have to pass an iterable thing (such as an array) of multiple promises to `Promise.all()`, not a single promise (`other`). But why are you using `Promise.all` at all here, if you have only a single promise? Just `await other;`. – Bergi Jul 03 '22 at 22:23

2 Answers2

2

I'm going to break this down in reverse order.

First, Promise.all() is for waiting for multiple promises, so instead of:

await Promise.all(other);

You can just do

await other;

The second issue is that you should usually avoid new Promise. It's used incorrectly in your case, and you also shouldn't use async functions inside new Promise, it makes no sense. That simplifies it to:

const other = (async function () {
    updatedFields.last_login_at = newDateNow();
    if (updatedFields.isActivated) {
        updatedFields.activated_at = newDateNow();
        updatedFields.deactivated_at = null;
    } else if (updatedFields.isActivated === false) {
        updatedFields.deactivated_at = newDateNow();
        updatedFields.activated_at = null;
    }
})();

await other;

The next issue is that you're not doing anything in the this function that actually takes advantage of async/await/promises, so you should really just get rid of async and await for these cases.

That reduces your code snippet to:

updatedFields.last_login_at = newDateNow();
if (updatedFields.isActivated) {
  updatedFields.activated_at = newDateNow();
  updatedFields.deactivated_at = null;
} else if (updatedFields.isActivated === false) {
  updatedFields.deactivated_at = newDateNow();
  updatedFields.activated_at = null;
}
Evert
  • 93,428
  • 18
  • 118
  • 189
-1

When a promise is created, its state is pending, and when you await it, it waits until it is rejected or resolved. Since you don't resolve or reject, it does not work. Also, Promise.all function's first argument should be an array

enter image description here

 const other = new Promise(function (resolve,reject) {
    updatedFields.last_login_at = newDateNow();
    if (updatedFields.isActivated) {
        updatedFields.activated_at = newDateNow();
        updatedFields.deactivated_at = null;
    } else if (updatedFields.isActivated === false) {
        updatedFields.deactivated_at = newDateNow();
        updatedFields.activated_at = null;
    }
    resolve(updatedFields)
    });

await Promise.all([other]);
// you can do following if you have single promise
// await other
Deniz Gürsoy
  • 120
  • 1
  • 3
  • 1
    And where is the explaination why you added the Array to Promise.all()? – Christopher Jul 03 '22 at 21:51
  • 1
    It seems to execute the Promise also without the `await` line. When I comment that line out, the values still get written. – Zoe Jul 03 '22 at 21:57
  • 1
    [Never pass an `async function` as the executor to `new Promise`](https://stackoverflow.com/q/43036229/1048572)! – Bergi Jul 03 '22 at 22:19