0

I am trying to implement a functionality where it allows the user to tap the "Add Photo" component and their device photo library pops up to add/choose an image to display. However, I am testing this and although my console.log(result) seems to be working & outputting fine it is not displaying the image, the component stays the same as I have upon startup (check image attached). Note, I am using expo with IOS simulator, I also wanted to ask if implemented correctly, is it maybe a simulation environment causing this to not display?

screen after choosing an image

User Profile.js:

import React, { useState, useEffect } from 'react';
import { View, Text, TextInput, TouchableOpacity, Image, StyleSheet, ScrollView } from 'react-native';
import * as ImagePicker from 'expo-image-picker';
import Icon from 'react-native-vector-icons/FontAwesome';
import * as Localization from 'expo-localization';

const Profile = ({ route }) => {
  const user = route.params.user.user;
  const [username, setUsername] = useState(user.username);
  const [password, setPassword] = useState(user.password);
  const [email, setEmail] = useState(user.email);
  const [phoneNumber, setPhoneNumber] = useState('');
  const [profileImage, setProfileImage] = useState(null);
  const [showPassword, setShowPassword] = useState(false);
  const [joinedDate, setJoinedDate] = useState(null);
  const deviceLanguage = Localization.locale;

  const pickImage = async () => {
    try {
      const result = await ImagePicker.launchImageLibraryAsync({
        mediaTypes: ImagePicker.MediaTypeOptions.Images,
        allowsEditing: true,
        aspect: [4, 3],
        quality: 1,
      });
      if (!result.cancelled) {
        setProfileImage(result.uri);
        console.log('Image picker result:', result);
      }
    } catch (error) {
      console.log('Error picking image', error);
    }
  };  

  const handleSaveChanges = () => {
    console.log('Updated Data:');
    console.log('User Name:', username);
    console.log('Password:', password)
    console.log('Email:', email);
    console.log('Phone Number:', phoneNumber);
    console.log('Image:', profileImage);
  };

  useEffect(() => {
    (async () => {
      if (Platform.OS !== 'web') {
        const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
        if (status !== 'granted') {
          alert('Sorry, we need camera roll permissions to make this work.');
        }
      }
    })();
    
    const currentDate = new Date();
    const formattedDate = currentDate.toISOString().split('T')[0];
    setJoinedDate(formattedDate);
  }, []);

  return (
    <ScrollView>
      <View style={styles.container}>
        <TouchableOpacity onPress={pickImage}>
          <View style={styles.profileImageContainer}>
            {profileImage ? (
              <Image source={{ uri: profileImage }} style={styles.profileImage} />
            ) : (
              <Text style={styles.addPhotoText}>Add Photo</Text>
            )}
          </View>
        </TouchableOpacity>
        <View style={styles.infoContainer}>
          <Text style={styles.title}>Profile Setting</Text>
          <View style={styles.fieldContainer}>
            <Text style={styles.fieldLabel}>Username:</Text>
            <TextInput
              style={styles.input}
              value={username}
              onChangeText={(text) => setUsername(text)}
              placeholderTextColor="gray"
            />
          </View>
          <View style={styles.fieldContainer}>
            <Text style={styles.fieldLabel}>Password:</Text>
            <View style={styles.passwordInput}>
              <TextInput
                style={styles.passInput}
                placeholder="Password"
                onChangeText={(text) => setPassword(text)}
                value={password}
                secureTextEntry={!showPassword} 
                placeholderTextColor="gray"
              />
              <TouchableOpacity onPress={() => setShowPassword(!showPassword)} style={styles.eyeIcon}>
                <Icon
                  name={showPassword ? 'eye' : 'eye-slash'}
                  size={20}
                  color="gray"
                />
              </TouchableOpacity>
            </View>
          </View>
          <View style={styles.fieldContainer}>
            <Text style={styles.fieldLabel}>Email:</Text>
            <TextInput
              style={styles.input}
              value={email}
              onChangeText={(text) => setEmail(text)}
              placeholderTextColor="gray"
            />
          </View>
          <View style={styles.fieldContainer}>
            <Text style={styles.fieldLabel}>Phone Number:</Text>
            <TextInput
              style={styles.input}
              onChangeText={(text) => setPhoneNumber(text)}
              value={phoneNumber}
              placeholderTextColor="gray"
            />
          </View>
          <View style={styles.fieldContainer}>
            <TextInput style={styles.fieldLabel}>Joined Date:</TextInput>
            <TextInput style={styles.input}>{joinedDate}</TextInput>
          </View>
          <View style={styles.fieldContainer}>
            <TextInput style={styles.fieldLabel}>Device Language:</TextInput>
            <TextInput style={styles.input}>{deviceLanguage}</TextInput>
          </View>
          <TouchableOpacity style={styles.saveButton} onPress={handleSaveChanges}>
            <Text style={styles.buttonText}>Save Changes</Text>
          </TouchableOpacity>
        </View>
      </View>
    </ScrollView>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    backgroundColor: '#fff',
  },
  profileImageContainer: {
    marginTop: 20,
    width: 120,
    height: 120,
    borderRadius: 60,
    backgroundColor: '#E0E0E0',
    justifyContent: 'center',
    alignItems: 'center',
  },
  profileImage: {
    width: 120,
    height: 120,
    borderRadius: 60,
  },
  addPhotoText: {
    fontSize: 16,
  },
  infoContainer: {
    width: '80%',
    marginTop: 20,
  },
  title: {
    fontSize: 20,
    fontWeight: 'bold',
    marginBottom: 20,
  },
  input: {
    height: 40,
    borderColor: 'gray',
    borderWidth: 1,
    borderRadius: 8,
    marginBottom: 16,
    paddingHorizontal: 10,
  },
  passwordInput: {
    flexDirection: 'row',
    alignItems: 'center',
    borderWidth: 1,
    borderColor: 'gray',
    borderRadius: 8,
    marginBottom: 16,
    paddingHorizontal: 10,
  },
  passInput: {
    flex: 1,
    height: 40,
    borderColor: 'gray',
    borderWidth: 0,
    borderRadius: 0,
    marginBottom: 0,
    paddingHorizontal: 0,
  },
  eyeIcon: {
    padding: 10,
  },
  labelText: {
    color: 'gray',
    marginTop: 12,
    textAlign: 'center',
  },
  dateOfBirthText: {
    color: 'black',
    marginTop: 12,
    textAlign: 'center',
  },
  inputHalf: {
    height: 40,
    borderColor: 'gray',
    borderWidth: 1,
    borderRadius: 8,
    marginBottom: 16,
    paddingHorizontal: 10,
    flex: 1,
    marginRight: 5,
  },
  inputThird: {
    height: 40,
    borderColor: 'gray',
    borderWidth: 1,
    borderRadius: 8,
    marginBottom: 16,
    paddingHorizontal: 10,
    flex: 1,
    marginRight: 5,
  },
  addressRow: {
    flexDirection: 'row',
  },
  saveButton: {
    backgroundColor: '#5CB85C',
    borderRadius: 8,
    paddingVertical: 12,
    alignItems: 'center',
  },
  buttonText: {
    color: '#fff',
    fontSize: 16,
    fontWeight: 'bold',
  },
  fieldContainer: {
    marginBottom: 0,
  },
  fieldLabel: {
    fontSize: 16,
    marginBottom: 8,
    color: 'gray',
  },
});
export default Profile;

I tried debugging and this is the output for console.log(result) on line 28:

Image picker result: Object {
  "assets": Array [
    Object {
      "assetId": "99D53A1F-FEEF-40E1-8BB3-7DD55A43C8B7/L0/001",
      "base64": null,
      "duration": null,
      "exif": null,
      "fileName": "IMG_0004.JPG",
      "fileSize": 2321139,
      "height": 1668,
      "type": "image",
      "uri": "file:///Users/besabunjaku/Library/Developer/CoreSimulator/Devices/B3DC7595-6F7F-44A4-874E-B96D527973B3/data/Containers/Data/Application/83A2BCEE-AB17-4A5C-AC82-012BC9617172/Library/Caches/ExponentExperienceData/%2540anonymous%252FHalaFinds-9c96a55d-e687-44f0-afcb-48668cf9406a/ImagePicker/02AB4D6E-AFFA-4E06-9B22-5CA87261A85A.jpg",
      "width": 1668,
    },
  ],
  "canceled": false,

1 Answer 1

0

The result contains the Array named assets, but you treat it as the Object, hence it's cause problem, to fix it, just use:

setProfileImage(result.assets[0].uri);
Sign up to request clarification or add additional context in comments.

1 Comment

If I add the index in I get this error, Error picking image [TypeError: Cannot read property 'uri' of undefined]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.