0

Context

I have this piece of code to force app update, that checks whether an update is needed and is supposed to return true or false depending on the version number of the user's app vs the App Store version. This seems to be working correctly when the version number of the user's app is lower, because it stores the right url in the website variable:

  let website = ''
  const isLatestVersion = async (): Promise<boolean> => {
    await VersionCheck.needUpdate({
      packageName: 'com.tfp.numberbomb',
    }).then((res) => {
      if (res.isNeeded) {
        website = res.storeUrl
        return true // open store if update is needed.
      } else return false
    })
  }

Problem

It doesn't work correctly when the version number of the user's app is equal/higher. This is the function where I am using the function from above. For some reason, the logic executes showPopup() even if the response from the function is false. What am I doing wrong?:

  const handleBiometricLogin = async () => {
    if (!(await isLatestVersion())) {
      await showPopup()
      return
    }
    ... // rest of the logic that doesn't run even when it's supposed to because of the return statement

Additional info

showPopup() function just for reference:

const showPopup = async () => {
    Alert.alert(
      translations['errors.login.update.title'] ?? 'Download Available',
      translations['errors.login.update.body'] ??
        'There is a new download available on the app store. Please update to gain access',
      [
        { text: translations['form.no-answer'] ?? 'No' },
        {
          text: translations['form.yes-answer'] ?? 'Yes',
          onPress: () => handleOpenLink(website, translations),
        },
      ],
    )
  }

I feel like I am doing the async and await stuff correctly, and I tried to search for possible duplicates but it's difficult to find anything

Saamer
  • 4,687
  • 1
  • 13
  • 55
  • Isn't that the point? You're using the NOT operator (`!`) which turns `false` into `true` (and vice versa). – Kelvin Schoofs Jul 25 '21 at 16:58
  • @KelvinSchoofs thanks for your response! I made some edits to make it clearer, but basically we only want to run the code and show the popup if it's NOT the latest version. – Saamer Jul 25 '21 at 17:02
  • `website` should be passed through. Don't rely on a member in an outer scope. Passing it through is trivial. – Roamer-1888 Jul 26 '21 at 10:12

1 Answers1

4

I wonder how TypeScript hasn't caught this, but the problem is that your function returns a Promise<void> instead of a Promise<boolean>. You never return anything from isLatestVersion, so it ends up with undefined, and your inverted condition always runs the if block.

The underlying issue is with awaiting a .then(…) chain - you want to use either then and return:

const isLatestVersion = (): Promise<boolean> => {
//                     ^ no async
  return VersionCheck.needUpdate({
//^^^^^^
    packageName: 'com.greenshield.mobileclaims',
  }).then((res) => {
    console.log(res)
    return res.isNeeded
  })
}

or only await:

const isLatestVersion = async (): Promise<boolean> => {
  const res = await VersionCheck.needUpdate({
//            ^^^^^
    packageName: 'com.greenshield.mobileclaims',
  });
//  ^ no .then()
  console.log(res)
  return res.isNeeded
}
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Yup! This is it, but I think you meant `return !res.isNeeded`. Or I can rename the function to isUpdateNeeded – Saamer Jul 25 '21 at 17:13
  • 1
    @Saamer OP has `if (res.isNeeded) { …; return true } else return false` which I abbreviated to `return res.isNeeded` without changing functionality. But yeah you're right, the function name doesn't make sense. – Bergi Jul 25 '21 at 17:13
  • Thanks for showing me the answer in both methods, will probably refer to this answer a lot! – Saamer Jul 25 '21 at 17:15