0

I am trying to check the progress of a listening session stored in AsyncStorage on React Native. My aim is to show progress (stored in a form of a number) against total lines (number).

I have this working code that outputs the total lines (sourced from a different API using fetch, not the problem here), but I can't seem to get the variable i declared outside of async function to be updated inside of the .then block, to be used in the return statment below.

Here's the (half)working code:


    ....//other existing codes in a React functional component

    //this is the async code that checks the store data in AsyncStorage
    const checkProgressListening = async(name) => {
        let response = await AsyncStorage.getItem(name+'-LISTENING_SESSION')
        let json = await JSON.parse(response)
        return json;
    }

    //this is the code that will be rendered in RNUILIB GridList
    const renderItemModule = ({item, index}) => {
        //declaring a variable outside of the .then function block below
        let progress = null;

        checkProgressListening(item.englishName).then(async (data) => {
            if(data != null){
                progress = data.number
            }
        }).catch((error) => {
            console.log(error)
        })

        return (
            <Text>{progress}/{totalnumberoflines}</Text>
        )
    }

    ...//other existing code
    return(
        <GriddList
            ...
            data={dataItems}
            renderItem={renderItemModule}
        />
    )

I tried to re-assign the variable progress with a new value from inside of the .then async block, but unsuccessful so far.

I've referred to this article on StackOverflow, but still couldn't get it working Set value of global variable inside async function or inside promise?

Hafiz Hanif
  • 361
  • 1
  • 3
  • 20
  • 2
    This exact question is asked dozens of times a day on Stackoverflow [How to return values from async functions using async-await from function?](https://stackoverflow.com/questions/49938266/how-to-return-values-from-async-functions-using-async-await-from-function) – Andy Ray Feb 28 '23 at 04:25

1 Answers1

1

This seems like a timing issue.

In the renderItemModule function, the return statement executes without waiting for the promise to resolve. What is happening is that

  1. progress if defined with the value null
  2. The checkProgressListening function is called and the code begins accessing the AsyncStorage
  3. The renderItemModule function returns with the value of progress still null.
  4. The async function attached to the promise executes and sets the value of progress, but only after renderItemModule has returned null. This is because the renderItemModule function isn't waiting for the callback to set the value of progress before it is returned.

You want to consider making renderItemModule asynchronous:

const renderItemModule = async ({item, index}) => {
    let progress = null;

    let data = await checkProgressListening(item.englishName);
    if (data != null){
        progress = data.number;
    }

    return (
        <Text>{progress}/{totalnumberoflines}</Text>
    )
}

Because this is an async function and it uses await when calling checkProgressListening, the function does not return until the promise is resolved.

Unfortunately, it might get a bit tricky to integrate an asynchronous version of checkProgressListening and may mean that you need to make many more functions asynchronous.

I'mAUserNow
  • 135
  • 6