2

I am trying to implement top level await in my react native & expo environment so I can pull data from AsyncStorage and store it in a variable to use globally in my app.

I'm running the app on an android emulator. All I want to do is get the data and use it in my application, but the the variable always returns an empty object when called outside the async function. It seems to apply a value to the variable before the data from AsyncStorage is done loading.

async function getData(){
  try {
    const value = await AsyncStorage.getItem('redditInsights')
      console.log('----------- getStore insights ---------')
      const insights = JSON.parse(value)
      console.log(insights) //  -------------> returns desired data
      return insights

  }
  catch (error) {
    console.log(error)
  }
}

const outsights = getData()
console.log("-------------------- outsights---------------------")
console.log(outsights) // ----------------------> returns empty object

I know I can pull the data inside an async function, but I can't use that data anywhere except inside the async function. I can't call a variable declared inside async outside of the function without it trying to apply a value to the variable before the data is even pulled.

Ideally I would simply store the data into a variable to use wherever I want without an async function like so, but this requires top level await support:

 const value = await AsyncStorage.getItem('redditInsights')
 const insights = JSON.parse(value)

I tried implementing top level await through numerous flags (--harmony-top-level-await, --experimental-repl-await, --experimental-top-level-await) at npm start like so: npm start --flag to no avail. I also upgraded to node v14.15.1 which is suppose to support top level await, but I still get an error.

How do I implement top level await in my react native & expo environment so I can use the data in my AsyncStorage

Or if anyone knows a better way to get my data from AsynStorage, I'm more than willing to try it out!!

Adam
  • 123
  • 10
  • You can get the data from ```AsyncStorage``` wherever you want and write the code in every component you need but if you want to use it across multiple components you should definitely use context or redux to achieve that or manually use prop drilling. – Shayan Dec 15 '20 at 18:24
  • Could you elaborate on how to do that with redux or prop driling? or provide some resources? – Adam Dec 15 '20 at 18:36
  • I think [this](https://kentcdodds.com/blog/how-to-use-react-context-effectively) article will be more than enough to use context in your application. If you don't have any experience with redux I suggest you be a little bit comfortable with context and after that use redux. But you can set the value of the state that you are going to use in the whole app within ```useEffect``` hook in context component or if you are using class based components use ```componentDidMount``` and for these you can check official [react docs](https://reactjs.org/). – Shayan Dec 15 '20 at 18:44
  • Ok, thanks I'll check them out and let you know if they work. – Adam Dec 15 '20 at 18:58
  • I'm sorry your resources are too opaque and I am yet unable to pull data properly from AsyncStorage. Please provide a clear example that would replace the code provided above and address the issues mentioned in the post – Adam Dec 20 '20 at 18:53

1 Answers1

0

The simple answer is this is not possible.

There's a more detailed answer about top level await in react-native here which says that React Native doesn't meet the requirements for top level await (uses node modules not ECMAScript native modules).

But your code sample has a mistake, you could declare a top level variable insights and assign the result of your async data to it. Your mistake is using the return value of getData you would need to declare a top level variable with let and then assign the result to it (so instead of return insights) you would do something like topScopeInsights = insights after a let topScopeInsights.

But, this doesn't make any sense, because you won't know if the data has arrived yet. The app will boot with your variable undefined and then you'll need to check if it has arrived or not. That's what promises are for.

So, back to my original answer, this is not possible. :-(

chmac
  • 11,757
  • 3
  • 32
  • 36