Search code examples
javascriptreact-nativees6-promise

How to export object based on conditions in react-native?


I want to export an objects based on conditions for example first I check some which language stored in 'AsyncStorage' then based on languages I return a particular object.

file: lang.js

import AsyncStorage from '@react-native-community/async-storage';
let exportingLang = {};

AsyncStorage.getItem('@lang').then(language=> {
    if(language){
        if(language === "hindi") exportingLang = {
           name: 'a hindi name'
        };
        else if(language === "panjabi") exportingLang = {
           name: 'a panjabi name'
        };
        else exportingLang = {
           name: 'a english name'
        };;
    }
});

export const Lang = exportingLang;

file: post.js

import {Lang} from 'lang';

export default Post = props => {

    return (
        <Text>{Lang.name}</Text>
    );
}

but the above code does not work.


Solution

  • The first thing to note here is that getItem returns a JavaScript Promise according to the documentation. With the way JavaScript works, we cannot get the values out of Promises and export them, without resolving or rejecting the Promise, more on that here. To explain it in terms of your example, you could assign a value to the exportingLang, but it will almost certainly return the initial empty object {} that you initialized it to because the Promise assignment happens asynchronously, that is, it needs to wait for the storage system to find the @lang key, then return its value which can take a while (hence the need for a Promise).

    If the point of having the lang.js file is to avoid typing the if statements over and over again, then that's all fine (otherwise I would just use the getItem Promise once in the Component I need the value in). I would first make sure that we export the results returned from the Promise as follows:

    lang.js

    export default AsyncStorage.getItem('@lang').then(language => {
      let exportingLang = {name: 'default'};
      if (language) {
        if (language === 'hindi')
          exportingLang = {
            name: 'a hindi name',
          };
        else if (language === 'panjabi')
          exportingLang = {
            name: 'a panjabi name',
          };
        else
          exportingLang = {
            name: 'a english name',
          };
      }
      return exportingLang;
    });
    

    This would in-turn give me another Promise as an export.

    Secondly, you cannot use values directly from a Promise into a React render method. You need to assign it to a state using useState or useEffect. You can read more on this here.

    For simplicity's sake, I have used it in a Component as follows:

    import langPromise from './lang';
    
    export default class App extends Component {
      state = {
        lang: { name: '' },
      };
    
      async componentDidMount() {
        const lang = await langPromise.then(lang => this.setState({ lang }));
      }
    
      render() {
        return (
          <View>
            <Text>{this.state.lang.name}</Text>
          </View>
        );
      }
    }
    

    Please let me know if you have any further questions.