I am developing a mobile app, which uses React-Native, Redux and React-Native-Contacts.
In an action creator, I am trying to call a function (from React-Native-Contacts), which has callbacks (rather than promises). Following is my code.
I want the action "acContactImport" to wait for the helper function "fContactImport" to finish before proceeding to the "dispatch" statement. It does not wait for it. How can I make it wait for it?
// Action Creator:
import Contacts from 'react-native-contacts';
import { PermissionsAndroid } from 'react-native';
export const acContactImport = (userID) => {
return async (dispatch) => {
let contactList = [];
try {
// The following statement should be executed asynchronously.
// However, it is not. How can I make it asynchronous?
contactList = await fContactImport();
dispatch({
type: CONTACT_IMPORT,
payload: { contactList: contactList },
});
}
catch (err) {
console.log("acContactImport - catch: ", err);
}
};
};
// Helper Function 1
export const fContactImport = async () => {
let contactList = [];
if (Platform.OS === "android") {
PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.READ_CONTACTS, {
title: "Contacts",
message: "This app would like to view your contacts."
})
.then(() => {
contactList = _loadContacts();
});
} else {
contactList = _loadContacts();
}
}
// Helper Function 2
export const _loadContacts = () => {
Contacts.getAll((err, data2) => {
if (err) {
return [];
}
else {
let candidates = [];
for (let i = 0; i < data2.length; i++) {
let candidateObject = { name: candidateRecord.givenName + " " + candidateRecord.middleName + " " + candidateRecord.familyName };
candidates.push(candidateObject);
}
return contactList;
}
});
}
Apparently, the problem is NOT in the action creator, but in the helper functions, which do not support the new style of promises (async/wait). So, here is the solution...
// Action Creator:
// No changes are required. Original code is good.
// Helper Function 1
export const fContactImport = async () => {
let contactList = [];
if (Platform.OS === "android") {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.READ_CONTACTS,
{
title: "Contacts",
message: "This app would like to view your contacts."
},
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
contactList = await _loadContacts();
} else {
console.log('Contacts access denied');
}
} catch (err) {
console.warn(err);
}
} else {
contactList = await _loadContacts();
}
return contactList;
}
// Helper Function 2
export const _loadContacts = () => {
return new Promise((resolve, reject) => {
Contacts.getAll((err, data2) => {
if (err) {
reject([]);
}
else {
let candidates = [];
for (let i = 0; i < data2.length; i++) {
let candidateObject = { name: candidateRecord.givenName + " " + candidateRecord.middleName + " " + candidateRecord.familyName };
candidates.push(candidateObject);
}
resolve(candidates);
}
});
});
}