1

This code doesn't work:

// within an async function
let user, created
if (someCondition) {
  [user, created] = await User.findOrCreate({ /* some options */ })
}
console.log(user) // undefined

But this works fine:

// within an async function
let myArray
if (someCondition) {
  myArray = await User.findOrCreate({ /* some options */ })
}
console.log(myArray[0]) // the user object, as expected

And this works too:

// within an async function
if (someCondition) {
  let [user, created] = await User.findOrCreate({ /* some options */ })
  console.log(user) // the user object, as expected
}

I'm declaring user and created outside of the conditional scope because I need those variables at function-level scope. Seems so weird that my first piece of code doesn't work, it's like the destructuring is only working if the let keyword is used before the array. According to this, it seems like that shouldn't be necessary.

Glenn
  • 4,195
  • 9
  • 33
  • 41
  • 1
    What does `await User.findOrCreate()` return? – evolutionxbox Jul 27 '20 at 17:05
  • 5
    If the third code block works, then the first one should also work. Is `someCondition` falsy in the first scenario by any chance? – adiga Jul 27 '20 at 17:06
  • @evolutionxbox it always returns an array with an object and a boolean (via a promise). It's a sequelize method. – Glenn Jul 27 '20 at 17:24
  • @adiga the condition is not falsey, I've confirmed with other tests that the block in question is running in all cases. – Glenn Jul 27 '20 at 17:26
  • 1
    [The first example works as expected.](https://codesandbox.io/s/kind-lamarr-e1zl3?file=/src/index.js) Please make sure you give a [mcve] so we can help. – evolutionxbox Jul 27 '20 at 17:30
  • @evolutionxbox hmm, sorry I updated my comment to state that the values were returned via a promise. Does that still work in your example? – Glenn Jul 27 '20 at 17:38
  • My example uses a [“thenable”](https://stackoverflow.com/questions/29435262/regarding-promises-a-specification-what-is-the-difference-between-the-terms-t) and works like a promise in this case. – evolutionxbox Jul 27 '20 at 17:40
  • I have [created a fiddle](https://jsfiddle.net/adigas/xec0hd51/) to mimic your issue. It works as intended. – adiga Jul 27 '20 at 17:51
  • Thanks @adiga. Yeah, seems like it works no problem in your example as well as evolutionxbox's. Still trying and hunting for anything that would prevent it from working on my end. Going to try upgrading node as a long shot. – Glenn Jul 27 '20 at 17:55
  • If you are doing object destructuring assignment separate from declaration, you need to wrap the assignment in parentheses. Ref - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#syntax – Pranaya Tomar May 26 '22 at 11:11

1 Answers1

1

As demonstrated in the live code snippet below, the answer is yes. Destructuring assignments work on the results of awaited function calls just as they do on synchronous function calls.

const syncFunction = () => ({ hello: 'world' });
const asyncFunction = async () => ({ foo: 'bar' });

const main = async () => {
  const { hello } = syncFunction();
  const { foo } = await asyncFunction();
  console.log({ hello, foo });
}

main();
GirkovArpa
  • 4,427
  • 4
  • 14
  • 43
  • 1
    There is already a fiddle created in the comments to show that OP's code is not reproducible. The question is off-topic. So, please flag it instead of answering. The help center says answer only well-asked questions. This question has no future value and [roomba](https://stackoverflow.com/help/roomba) can't delete it since it has an upvoted answer. – adiga Jul 28 '20 at 14:39