Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Native: Chain Async Calls. e.g to AsyncStorage?

I'm trying to chain several calls to AsyncStorage.getItem() but cannot seem to get the calls to trigger in the correct order. I seem to manage to drop out of the loop with the last item completed before earlier items. It appears that React uses a different syntax for promises than how jQuery would work.

In this example I am trying to chain calls to get vars v1, v2, v3. v3 triggers a refresh of the UI for which vars v1 and v2 are required. My code for two chained vars is as follows:

AsyncStorage.getItem("v1")
.then(
    (value) => {
        if (value !== null){
            varCollection.v1 =value
        }
    }
)
.then( () => {
    AsyncStorage.getItem("v3")
    .then((value) => {
        if (value !== null){
            varCollection.v3 = value;
        }else{
            varCollection.v3 = "default value";
        }
    })
    .done()
})
.done();

This appears to work but it may be simply luck that causing it to work as when I add another link to the chain, things go wrong.

AsyncStorage.getItem("v1")
.then(
    (value) => {
        if (value !== null){
            varCollection.v1 =value
        }
    }
)
.then( () => {
    AsyncStorage.getItem("v2")
    .then((value) => {
        if (value !== null){
            varCollection.v2 = value;
        }
    })
    .done()
})
.then( () => {
    AsyncStorage.getItem("v3")
    .then((value) => {
        if (value !== null){
            varCollection.v3 = value;
        }else{
            varCollection.v3 = "default value";
        }
    })
    .done()
})
.done();

This results in v3 altering and triggering the state of the app to change even though v2 may not have been assigned yet.

Calling console.log() on each of the vars in props.varCollection from getInitialState() of child elements shows v1 is present but v2 isn't or vice versa. I have also tried nesting my calls to create the chain which I realised gets messy quickly.

* Update * Further to SLacks and Bergi's suggestions I have also tried the following:

AsyncStorage.getItem("v1")
.then((value) => {
    if (value !== null){
        v1 = value;
    }
})
.then( () =>{
    return( 
        AsyncStorage.getItem("v2")
        .then((value) => {
            if (value !== null){
                v2 = value;
            }
        })
    )
})
.then( () => {
    return(
        AsyncStorage.getItem("v3")
        .then((value) => {
            if (value !== null){
                v3 = value;
            }
        })
    )
})
.done();

and

AsyncStorage.getItem("v1")
.then((value) => {
    if (value !== null){
        v1 = value;
    }
})
.then( () =>
    ( 
        AsyncStorage.getItem("v2")
        .then((value) => {
            if (value !== null){
                v2 = value;
            }
        })
    )
)
.then( () => 
    (
        AsyncStorage.getItem("v3")
        .then((value) => {
            if (value !== null){
                v3 = value;
            }
        })
    )
)
.done();

but still get stuck at the second call.

* /Update *

What is the correct way to chain Async calls in React Native?

like image 645
Moss Palmer Avatar asked Jan 09 '23 06:01

Moss Palmer


1 Answers

I'm not sure why the suggested syntax from Bergi did not work but I found that separating the call and assignment before and after the then statement allowed strict control of ordering and that the return statement should only return the promise from the last call in each block. This may not be the best way to do it, but it seems to work quite well for sequential synchronous reads.

AsyncStorage.getItem("v1")
.then( (value) =>
      {
        this.setState({v1:value})
        return AsyncStorage.getItem("v2")
      }
)
.then( (value) =>
    {
        this.setState({v2: value})
        return AsyncStorage.getItem("v3")
    }
)
.then( (value) =>
    {
        this.setState({v3:value})
        return AsyncStorage.getItem("v4")
    }
)
.then( (value) =>
    {
        return this.setState({v4:value})
    }
).done();

You can see it in action at https://rnplay.org/plays/51t0cQ

like image 58
Moss Palmer Avatar answered Jan 16 '23 22:01

Moss Palmer