State is not updating same time due to this previous image is uploading to the server

Viewed 44

I am using AWS S3 bucket for uploading images to the server and getting response from the server as image URL and then I am storing it into database but due to state not updating same time it is storing previous response

My CODE is here

const EditProfileScreen = ({ navigation, userdetails, adduser,imageUrl,addimage }) => {
    const [isModalVisible, setModalVisible] = useState(false);
    const [isChoosen, setChoosen] = useState(false);
    const [isLoading, setLoading] = useState(false);
    const [picture_url, setPictureUrl] = useState('');
    const [availableData, setAvailableData] = useState({
        name: userdetails.name,
        email: userdetails.email,
        zipcode: userdetails.zipcode,
        address: userdetails.address,
        phone: userdetails.phone,
        picture_url : userdetails.picture_url
    })
    const [selectedIMage,setSelectedimage] = useState({
        imageType : imageUrl.type,
        imageName : imageUrl.fileName,
        imagePath : imageUrl.uri
    })
    const handleImageChange = (awsImageurl) => {
        setPictureUrl(awsImageurl)
    } 
    const handleCaptureImage = (imgDetails) => {
        setSelectedimage({
            imagePath : imgDetails.uri,
            imageName : imgDetails.fileName,
            imageType : imgDetails.type
        })
    }

    const showToast = (alert) => {
        ToastAndroid.showWithGravity(
            alert,
            ToastAndroid.LONG,
            ToastAndroid.BOTTOM
        );
    };
    async function uploadToS3() {
        setLoading(true);

        const file = {
            uri: selectedIMage.imagePath,
            name: selectedIMage.imageName,
            type: selectedIMage.imageType
        }

        const options = {
            keyPrefix: "profile_pics/",
            bucket: "bucket",
            region: "ap-south-1",
            accessKey: "**********",
            secretKey: "***********",
            successActionStatus: 201
        }

        try {
            const response = await RNS3.put(file, options)
            if (response.status === 201) {
                console.log("Success: ", response.body);
                handleImageChange(response.body.postResponse.location);
                setLoading(false);

            } else {
                console.log("Failed to upload image to S3: ", response)
                setLoading(false);
            }
        } catch (error) {
            console.log("inside catch error",error)
            setLoading(false);
        }
    }

    const editUserDetails = async () => {
        setLoading(true);
        try {
            let user_id = null;
            let token = null;
            user_id = await AsyncStorage.getItem('user_id');
            token = await AsyncStorage.getItem('userToken');
            const pic_url = picture_url;
            var qs = require('qs');
            var data = qs.stringify({
                'name': availableData.name,
                'email': availableData.email,
                'zipcode': availableData.zipcode,
                'address': availableData.address,
                'phone': availableData.phone,
                'picture_url': pic_url
            });
            var config = {
                method: 'patch',
                url: `/users/${user_id}`,
                headers: {
                    'Authorization': `Bearer ${token}`,
                    'Content-Type': 'application/x-www-form-urlencoded'
                },
                data: data
            };
            console.log("userId:", user_id);
            if (user_id != null) {
                axios(config)
                    .then((response) => {
                        console.log(response.data.data);
                        adduser(response.data.data);
                        setTimeout(() => {
                            setLoading(false)
                            showToast(response.data.message);
                            navigation.navigate('ProfileScreen');
                        }, 1000);
                    }, (error) => {
                        console.log(error.response);
                        setLoading(false);
                    });
            }
        } catch (e) {
            console.log(e);
        }
    }

    const requestCameraPermission = async () => {
        if (Platform.OS === 'android') {
            try {
                const granted = await PermissionsAndroid.request(
                    PermissionsAndroid.PERMISSIONS.CAMERA,
                    {
                        title: 'Camera Permission',
                        message: 'App needs camera permission',
                    },
                );
                // If CAMERA Permission is granted
                return granted === PermissionsAndroid.RESULTS.GRANTED;
            } catch (err) {
                console.warn(err);
                return false;
            }
        } else return true;
    };

    const requestExternalWritePermission = async () => {
        if (Platform.OS === 'android') {
            try {
                const granted = await PermissionsAndroid.request(
                    PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
                    {
                        title: 'External Storage Write Permission',
                        message: 'App needs write permission',
                    },
                );
                // If WRITE_EXTERNAL_STORAGE Permission is granted
                return granted === PermissionsAndroid.RESULTS.GRANTED;
            } catch (err) {
                console.warn(err);
                alert('Write permission err', err);
            }
            return false;
        } else return true;
    };
    const captureImage = async (type) => {
        let options = {
            mediaType: type,
            maxWidth: 300,
            maxHeight: 550,
            quality: 1,
            videoQuality: 'low',
            durationLimit: 30, //Video max duration in seconds
            saveToPhotos: true,
        };
        let isCameraPermitted = await requestCameraPermission();
        let isStoragePermitted = await requestExternalWritePermission();
        if (isCameraPermitted && isStoragePermitted) {
            launchCamera(options, (response) => {
                handleCaptureImage(response);
                console.log('Response = ', response);

                if (response.didCancel) {
                    let alrt = "User cancelled camera picker";
                    showToast(alrt);
                    return;
                } else if (response.errorCode == 'camera_unavailable') {
                    let alrt = "Camera not available on device";
                    showToast(alrt);
                    return;
                } else if (response.errorCode == 'permission') {
                    let alrt = "Permission not satisfied";
                    showToast(alrt);
                    return;
                } else if (response.errorCode == 'others') {
                    showToast(response.errorMessage);
                    return;
                }
                console.log('base64 -> ', response.base64);
                console.log('uri -> ', response.uri);
                console.log('width -> ', response.width);
                console.log('height -> ', response.height);
                console.log('fileSize -> ', response.fileSize);
                console.log('type -> ', response.type);
                console.log('fileName -> ', response.fileName);
                addimage(response);

                if (imageUrl) {
                    setChoosen(true)
                    setModalVisible(!isModalVisible);
                    setTimeout(() => {
                        uploadToS3();
                    }, 2000);
        
                }
                else {
                    setChoosen(false)

                }
            });
        }
    };
    const chooseFile = (type) => {
        let options = {
            mediaType: type,
            maxWidth: 300,
            maxHeight: 550,
            quality: 1,
        };
        launchImageLibrary(options, (response) => {
            console.log('Response = ', response);
            handleCaptureImage(response) 
            if (response.didCancel) {
                let alrt = "User cancelled camera picker";
                showToast(alrt);
                return;
            } else if (response.errorCode == 'camera_unavailable') {
                let alrt = 'Camera not available on device';
                showToast(alrt);
                return;
            } else if (response.errorCode == 'permission') {
                let alrt = 'Permission not satisfied';
                showToast(alrt);
                return;
            } else if (response.errorCode == 'others') {
                showToast(response.errorMessage);
                return;
            }
            console.log('base64 -> ', response.base64);
            console.log('uri -> ', response.uri);
            console.log('width -> ', response.width);
            console.log('height -> ', response.height);
            console.log('fileSize -> ', response.fileSize);
            console.log('type -> ', response.type);
            console.log('fileName -> ', response.fileName);
            addimage(response);

            if (imageUrl) {
                setChoosen(true)
                setModalVisible(!isModalVisible);
                setTimeout(() => {
                    uploadToS3();
                }, 2000);
            }
            else {
                setChoosen(false)
            }
        });
    };


   

const mapStateToProps = (state) => {
    console.log(state);
    return {
        userdetails: state.userReducer.userProfile,
        imageUrl : state.userReducer.imageUrl
    }
}

const mapDispatchToProps = (dispatch) => {
    console.log(dispatch)
    return {
        adduser: (details) => dispatch(addUser(details)),
        addimage: (image_url) => dispatch(addImageToUpload(image_url))
    }
}
export default connect(mapStateToProps, mapDispatchToProps)(EditProfileScreen)

I am using redux for storing data and fetching user details from redux, I want the state to be updated at the same time so that the actual response stored into db and also if uploading first time it is throwing error because it is not getting details for uploading to the AWS s3 server. Any suggestions or help ? Thanks in advance

2 Answers

Maybe you can use asynchronous middleware for redux as Redux Thunk. Then you will be able to make your action dispatches as asynchronous.

I got the solution Instead of storing the captured data from camera or photo gallery into state I am directly sending the data into s3 bucket and it is working fine

Related