Zway
Zway

Reputation: 33

Console Warning : Possible unhandled promise rejection (id:0): TypeError: Cannot read property "launchImageLibrary" of null

Hello I get this Error when I start my app with "npx expo start"

Console Warning : Possible unhandled promise rejection (id:0): TypeError: Cannot read property "launchImageLibrary" of null

Here's my upload.tsx file:

import React, { useState } from 'react';
import { StyleSheet, View, Text, Button, Image } from 'react-native';
import { launchCamera, launchImageLibrary } from 'react-native-image-picker';
import { StackNavigationProp } from '@react-navigation/stack';
import { YourStackParamList } from '../type';

type HomeScreenProps = {
  navigation: StackNavigationProp<YourStackParamList, 'Home'>;
};

function UploadScreen({ navigation }: HomeScreenProps) {
  const [imageUri, setImageUri] = useState<string | null>(null);

  const openImagePicker = async () => {
    const result = await launchImageLibrary({
      mediaType: 'photo',
      quality: 1,
    });
  
    if (result.assets && result.assets.length > 0 && result.assets[0].uri) {
      setImageUri(result.assets[0].uri);
    } else {
      setImageUri(null);
    }
  };
  
  const openCamera = async () => {
    const result = await launchCamera({
      mediaType: 'photo',
      cameraType: 'back',
      quality: 1,
    });
  
    if (result.assets && result.assets.length > 0 && result.assets[0].uri) {
      setImageUri(result.assets[0].uri);
    } else {
      setImageUri(null); 
    }
  };
  

  return (
    <View style={styles.container}>
      <Text style={styles.text}> Upload</Text>
      <Button title="Sélectionner depuis la galerie" onPress={openImagePicker} />
      <Button title="Prendre une photo" onPress={openCamera} />
      {imageUri && <Image source={{ uri: imageUri }} style={styles.image} />}
    </View>
  );
}

export default UploadScreen;

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
  text: {
    color: '#0C1947',
    fontSize: 20,
    marginBottom: 20,
  },
  image: {
    width: 300,
    height: 300,
    marginTop: 20,
  },
});

My app.json

    {
  "expo": {
    "name": "oysterCVApp",
    "slug": "oysterCVApp",
    "version": "1.0.0",
    "orientation": "portrait",
    "icon": "./assets/icon.png",
    "userInterfaceStyle": "light",
    "splash": {
      "image": "./assets/splash.png",
      "resizeMode": "contain",
      "backgroundColor": "#ffffff"
    },
    "assetBundlePatterns": ["**/*"],
    "ios": {
      "supportsTablet": true,
      "infoPlist": {
        "NSCameraUsageDescription": "Cette application a besoin d'accéder à la caméra pour prendre des photos.",
        "NSPhotoLibraryUsageDescription": "Cette application a besoin d'accéder à la bibliothèque de photos pour sélectionner des images.",
        "NSPhotoLibraryAddUsageDescription": "Cette application a besoin d'ajouter des images à la bibliothèque de photos."
      }
    },
    "android": {
      "adaptiveIcon": {
        "foregroundImage": "./assets/adaptive-icon.png",
        "backgroundColor": "#ffffff"
      },
      "permissions": ["CAMERA", "READ_EXTERNAL_STORAGE", "WRITE_EXTERNAL_STORAGE"]
    },
    "web": {
      "favicon": "./assets/favicon.png"
    }
  }
}

and my package.json

    {
  "name": "oystercvapp",
  "version": "1.0.0",
  "scripts": {
    "start": "npx expo start src/App.tsx",
    "android": "expo start --android",
    "ios": "expo start --ios",
    "web": "expo start --web"
  },
  "dependencies": {
    "@react-navigation/native": "^6.1.9",
    "@react-navigation/native-stack": "^6.9.17",
    "@react-navigation/stack": "^6.3.20",
    "expo": "~50.0.6",
    "expo-permissions": "^14.4.0",
    "expo-status-bar": "~1.11.1",
    "react": "18.2.0",
    "react-native": "0.73.4",
    "react-native-image-picker": "^7.1.0"
  },
  "devDependencies": {
    "@babel/core": "^7.20.0",
    "@types/react": "~18.2.45",
    "@types/react-native": "^0.73.0",
    "typescript": "^5.1.3"
  },
  "private": true
}

Steps to Reproduce:

Start the app using npx expo start. Navigate to the upload screen. Attempt to select an image from the gallery or take a photo.

Expected Behavior: The app should allow users to select an image from the gallery or take a photo without any errors.

Additional Notes:

I have configured the necessary permissions for accessing the camera and gallery in app.json. I have verified that react-native-image-picker is installed correctly and updated to the latest version. Any help or guidance on resolving this issue would be greatly appreciated. Thank you!

Upvotes: 1

Views: 282

Answers (1)

Zway
Zway

Reputation: 33

Using expo-image-picker instead of react-native-image-picker

import React, { useState } from 'react';
    import { StyleSheet, View, Text, Button, Image, Alert } from 'react-native';
    import * as ImagePicker from 'expo-image-picker';
    import { StackNavigationProp } from '@react-navigation/stack';
    import { YourStackParamList } from '../type';
    
    type HomeScreenProps = {
      navigation: StackNavigationProp<YourStackParamList, 'Home'>;
    };
    
    function UploadScreen({ navigation }: HomeScreenProps) {
      const [imageUri, setImageUri] = useState<string | null>(null);
    
      const handleImagePickerResponse = (result: ImagePicker.ImagePickerResult) => {
        if (!result.cancelled && result.uri) {
          setImageUri(result.uri);
        }
      };
    
      const showImagePickerOptions = () => {
        Alert.alert("Sélectionner une image", "Choisissez l'option de sélection d'image", [
          {
            text: "Annuler",
            style: "cancel",
          },
          {
            text: "Prendre une photo",
            onPress: () => openCamera(),
          },
          {
            text: "Choisir depuis la galerie",
            onPress: () => openImagePicker(),
          },
        ]);
      };
    
      const openImagePicker = async () => {
        const permissionResult = await ImagePicker.requestMediaLibraryPermissionsAsync();
    
        if (permissionResult.granted === false) {
          alert("Vous avez refusé l'accès à la galerie d'images.");
          return;
        }
    
        const result = await ImagePicker.launchImageLibraryAsync({
          mediaTypes: ImagePicker.MediaTypeOptions.Images,
          quality: 1,
        });
    
        handleImagePickerResponse(result);
      };
    
      const openCamera = async () => {
        const permissionResult = await ImagePicker.requestCameraPermissionsAsync();
    
        if (permissionResult.granted === false) {
          alert("Vous avez refusé l'accès à la caméra.");
          return;
        }
    
        const result = await ImagePicker.launchCameraAsync({
          mediaTypes: ImagePicker.MediaTypeOptions.Images,
          quality: 1,
        });
    
        handleImagePickerResponse(result);
      };
    
      return (
        <View style={styles.container}>
          <Text style={styles.text}>Upload</Text>
          <Button title="Sélectionner une image" onPress={showImagePickerOptions} />
          {imageUri && <Image source={{ uri: imageUri }} style={styles.image} />}
        </View>
      );
    }
    
    export default UploadScreen;
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        backgroundColor: '#fff',
        alignItems: 'center',
        justifyContent: 'center',
      },
      text: {
        color: '#0C1947',
        fontSize: 20,
        marginBottom: 20,
      },
      image: {
        width: 300,
        height: 300,
        marginTop: 20,
      },
    });

Upvotes: 0

Related Questions