'undefined is not an object (evaluating 'item.phoneNumbers[0]')

I'm trying to display the list of contacts and in IOS it works fine but in ANDROID I get this error:

undefined is not an object (evaluating 'item.phoneNumbers[0]').

So far I have read that the reason this error comes up is because I should check first that a phone number exists before displaying it but that is something that I have already done in my code and I still get this error. If there is something I'm getting it wrong please let me know. Below I'll attach my code.

function ContactList({ selectedContacts, setSelectedContacts, contacts, selectedGuardian, setSelectedGuardian }) {
  const [checked, setChecked] = useState(false);
  const [filter, setFilter] = useState([]);
  const [search, setSearch] = useState('');
  const [checkedBox, setCheckedBox] = useState(false);

  useEffect(() => {
    setFilter(contacts);
  }, [contacts]);

  const searchFilter = (text) => {
    if (text) {
      const newData = contacts.filter((item) => {
        const itemData = item.name ? item.name.toUpperCase() : ''.toUpperCase();

        const textData = text.toUpperCase();
        return itemData.indexOf(textData) > -1;
      });
      setFilter(newData);
      setSearch(text);
    } else {
      setFilter(contacts);
      setSearch(text);
    }
  };

  // console.log('contacts: ',contacts);

  const onChangeValue = (item) => {
    const fullName = item.firstName;
    const phoneNumbers = item.phoneNumbers[0].digits;
    const phoneNumberAndroid = item.phoneNumbers[0].number;
    {Platform == 'ios' ? setSelectedContacts({ ...selectedContacts, [phoneNumbers]: !selectedContacts[phoneNumber] }) : setSelectedContacts({ ...selectedContacts, [phoneNumberAndroid]: !selectedContacts[phoneNumberAndroid] })};
    {Platform == 'ios' ? setSelectedGuardian([...selectedGuardian, { name: fullName, phone: phoneNumbers }]) : setSelectedGuardian([...selectedGuardian, { name: fullName, phone: phoneNumberAndroid }]) };
  };

  
 



  const renderItem = ({ item, index }) => {
    const phoneNumberAndroid = item.phoneNumbers[0].number;
    const phoneNumbers = item.phoneNumbers[0].digits;
    

    


    return (
      <SafeAreaView>
        <ScrollView>
          <TouchableOpacity
            onPress={() => {
              onChangeValue(item);
            }}
            style={{ flex: 1, flexDirection: 'row', borderTopWidth: 0.5, borderTopColor: 'grey' }}
          >
            <View style={{ flex: 1 }}>
              <Text onPress={() => setChecked(true)} style={{ fontSize: 20, marginHorizontal: 10 }}>
                {item.name + ' '}
              </Text>
              <Text style={{ fontSize: 17, marginHorizontal: 10, marginTop: 5, color: 'grey' }}>
              {item.phoneNumbers && item.phoneNumbers[0] && item.phoneNumbers[0].number}
              </Text>
            </View>
            <CheckBox
              style={{ width: 15, height: 15, paddingTop: 8 }}
              right={true}
              checked={ Platform == 'ios' ? !!selectedContacts[phoneNumbers] : !!selectedContacts[phoneNumberAndroid]}
              onPress={() => {
                onChangeValue(item, index);
              }}
            />
          </TouchableOpacity>
        </ScrollView>
      </SafeAreaView>
    );
  };

  return (
    <SafeAreaView style={styles.container}>
      <View style={styles.container}>
        <View
          style={{
            height: 40,
            justifyContent: 'center',
            backgroundColor: '#eeeeee',
            width: '90%',
            marginHorizontal: 20,
            marginTop: 15,
            borderRadius: 10,
          }}
        >
          <Feather name="search" size={20} color="grey" style={{ position: 'absolute', left: 32 }} />
          <TextInput
            placeholder="Search"
            placeholderTextColor="#949494"
            style={{
              left: 20,
              paddingHorizontal: 35,
              fontSize: 20,
            }}
            value={search}
            onChangeText={(text) => {
              searchFilter(text);
              setSearch(text);
            }}
          />
        </View>
        <FlatList
          style={{ marginTop: 15 }}
          data={filter}
          keyExtractor={(item) => `key-${item.id.toString()}`}
          renderItem={renderItem}
          refreshing={true}
          initialNumToRender={10}
          ListEmptyComponent={<Text message="No contacts found." />}
        />
      </View>
    </SafeAreaView>
  );
}
const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
  },
});

export default ContactList;


Solution 1:[1]

I first focused at this part of your code:

{Platform == 'ios' ? setSelectedContacts({ ...selectedContacts, [phoneNumbers]: !selectedContacts[phoneNumber] }) : setSelectedContacts({ ...selectedContacts, [phoneNumberAndroid]: !selectedContacts[phoneNumberAndroid] })};
{Platform == 'ios' ? setSelectedGuardian([...selectedGuardian, { name: fullName, phone: phoneNumbers }]) : setSelectedGuardian([...selectedGuardian, { name: fullName, phone: phoneNumberAndroid }]) };

From what I've noticed here, the difference if the Platform is iOS or Android is that phoneNumbers is used in iOS while phoneNumberAndroid is used in Android!

Then, I saw the 2 lines of code above:

const phoneNumbers = item.phoneNumbers[0].digits;
const phoneNumberAndroid = item.phoneNumbers[0].number;

If I'm not mistaken, Android here uses item.phoneNumbers[0].number.

So, the only reason I could think of the error showing is that item.phoneNumbers[0].number is invalid!

Though I'm not sure of this, I couldn't think of any other reason. Sorry if this is incorrect!

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1