You can't make DEFAULT_LANGUAGE
contain the fulfillment value rather than a promise unless you make loading the module exporting it wait until that asynchronous operation is complete. So you either:
Delay completion of that module's load until the value is available
Make it a promise and handle that where you use it
1 - Delaying module load using top-level await
You can only do that if your environment supports top-level await
, which many do now.
To use that to delay loading of that module until the asynchronous request is complete, you'd do this:
export const DEFAULT_LANGUAGE = await (async () => {
try {
const response = await AsyncStorage.getItem('appLanguage');
if (response) {
return response;
} else {
return 'English';
}
} catch (e) {
return 'English';
}
})();
Which can also be written as:
export const DEFAULT_LANGUAGE = await (async () => {
let language;
try {
language = await AsyncStorage.getItem("appLanguage");
} catch (e) {
}
return language || "English";
})();
or even:
export const DEFAULT_LANGUAGE = await AsyncStorage.getItem("appLanguage")
.catch(() => null)
.then(language => language || "English");
That does the asynchronous work, waits for it, and then allows the module load to occur.
Naturally, delaying module load like that may not be the best choice, it's very situation-dependent. But it's your only option if you need DEFAULT_LANGUAGE
to be the fulfillment value, not a promise.
2 - Making it a promise and waiting for it
Right now, you've made DEFAULT_LANGUAGE
a function. Nothing calls it. Instead, call it and store the returned promise:
export const DEFAULT_LANGUAGE_PROMISE = (async () => {
try {
const response = await AsyncStorage.getItem('appLanguage');
if (response) {
return response;
} else {
return 'English';
}
} catch (e) {
return 'English';
}
})();
Then, when using it, wait for promise fulfillment:
import { DEFAULT_LANGUAGE_PROMISE} from './translations';
import React, { useState } from 'react';
export const Welcome = () => {
const [appLanguage, setAppLanguage] = useState(null);
useEffect(() => {
// We don't have to worry about rejection, because you've set it
// up not to reject
DEFAULT_LANGUAGE_PROMISE.then(setAppLanguage);
}, []);
// ...
};
Note that Welcome
's rendering will have to handle the fact that appLanguage
will be null
at first in this scenario.
You might want to make your main entry-point component handle this, and then provide it to all components in the tree via context. There are all sorts of different ways to spin this.