1

I'm trying to save image to php application (made with laravel 6.0) using React Native. Here is my react native image picker

var ImagePicker = NativeModules.ImageCropPicker;

here is my image save function

addImages = async () => {
    const { image, images } = this.state
    const access_token = await AsyncStorage.getItem('access_token')

    try {

        let data = new FormData();

        images.map((image, i) => {
            data.append('id', id);
            data.append('uri', image.uri);
            data.append('type', image.mime);
            data.append('name', 'test.jpg');
        });

        fetch(apiConfig.apiUrl + '/api/save-image', {
            method: 'POST',
            headers: {        
                'Content-Type' : 'multipart/form-data',
                'Authorization': 'Bearer ' + access_token,
            },
            body:data
        })
            .then(function (response) {
                return response.json();
            })
            .then(function (data) {

                try {
                   console.log(data);                      

                } catch (error) {                     
                    console.log(error);
                }
            }.bind(this))
            .catch((error) => {
                console.log(error)
            });
    }catch (error) {
        console.log(error)
    }
}

Here is my php code

public function saveImage(Request $request)
{
    header( "Access-Control-Allow-Methods' => 'POST, GET, OPTIONS, PUT, DELETE");
    header("Access-Control-Allow-Origin: *");

    try {
        $file= array('file'=>$request->uri);
        Storage::disk('public')->put($request->imgName,File::get($file->file));

        return response()->json(['true'=>'Successfully Created'], 200);
    } catch (\Exception $e) {
        Log::info('vehicle image: ', [$e->getMessage()]);
        return response()->json(['error'=>$e], 200);
    }
}

When I try to save I'm getting SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data.

when I return the $request->uri I'm getting something like this file:///data/user/0/com.carup/cache/react-native-image-crop-picker/IMG_20191103_161929.jpg

How can I fix this?

How can I fix this?

2 Answers 2

1

You need to specify file name as the third parameter to data.append:

data.append('file', image.uri, 'test.jpg');
Sign up to request clarification or add additional context in comments.

7 Comments

It's getting with catch on fetch method in javascript
ok, so what's the actual response then? Could you please try response.text() and then console.log(data)?
This is the error Illuminate\Contracts\Filesystem\FileNotFoundException: File does not exist at path file:///data/user/0/com.carup/cache/react-native-image-crop-picker/IMG_20191103_161929.jpg
That's because you're using React Native file location on the backend. You should do this instead to access the uploaded file: $file = $request->file('file'); And then pass $file to Storage::put.
It's created the file. but file is damaged, i can't view it
|
0

Finally I have fixed it with Base64 method. Here is my code.

pick images with base64

  pickMultipleBase64=()=> {
    ImagePicker.openPicker({
        multiple: true,
        width: 300,
        height: 300,
        includeBase64: true,
        includeExif: true,
    }).then(images => {
        this.setState({
            images: images.map(image => {
               return {uri: `data:${image.mime};base64,`+ image.data, width: image.width, height: image.height,type:image.mime}
            }),
        });

    }).catch(e => alert(e));
}

And uploaded with other details like this

addImages = async () => {
    const { image, images, stockNo } = this.state
    const access_token = await AsyncStorage.getItem('access_token')
    if(access_token == null) {
        return(
            this.gotoLogin()
        )
    }
    this.setState({
        isLoading:true,
        message:'',
        status:true
    })
    try {
        let data = new FormData();
        images.map((image, i) => {

            data.append('id', id);
            data.append('stock', stockNo);
            data.append('chassis', chassis_no);
            data.append('file'+i, this.state.images[i].uri);
            data.append('type'+i, this.state.images[i].type);

            imageCount++
        });

        data.append('imageCount', imageCount);

        // console.log(data);
        fetch(apiConfig.apiUrl + '/api/save-image', {
            method: 'POST',
            headers: {
               'Authorization': 'Bearer ' + access_token,
            },
            body:data
        })
            .then(function (response) {
                return response.json();
            })
            .then(function (data) {
                console.log(data);
                imageCount = 0
                try {
                    this.setState({
                        isLoading: false,
                        message:data.true ? data.true:data.error,
                        messageColor:data.true ? CarColors.success : CarColors.error,
                        btnStatus:true
                        // chassis:''
                    })

                    if(data.true){
                        this.setState({
                            image:null,
                            images: null,
                        })
                    }
                } catch (error) {
                    this.removeToken();
                    console.log('1 '+error);
                }
            }.bind(this))
            .catch((error) => {
                this.setState({
                    isLoading: false,
                    message:'error',
                    messageColor:CarColors.error,
                })
                console.log(error)
            });

    }catch (error) {
        console.log(error)
    }

And my php(laravel) code is like this. Here I have created a new folder (with vehicle id) in storage and save images to separate folders.

public static function saveImage($request)
{
    $dir = "./storage/vehicle/" . $request->id;

    if (is_dir($dir) === false) {

        mkdir($dir);
    }
    DB::beginTransaction();
    try {

        for ($i = 0; $i < $request->imageCount; $i++) {

            $type = [];
            $file = 'file' . $i;
            $mime = 'type' . $i;
            $data = $request->$file;
            $type = explode('/', $request->$mime);
            $extension = $type[1];
            list($type, $data) = explode(';', $data);
            list(, $data) = explode(',', $data);
            $data = base64_decode($data);
            $Imgdata =Images::create([
                'vehicle_id' => $request->id,
                'img_name' => $i.'.'.$extension,
                'img_ext' => $extension,
                'img_order' => '0',
            ]);
            Storage::disk('vehicle')->put($request->id . '/' . $i . '.' . $extension, $data);
        }
        //Update Vehicle table ImageStatus

        $Vehicle = Vehicle::where('id',$request->id)->update([
            'img_status' => '1',
        ]);

        return response()->json(['true' => 'Successfully Uploaded'], 200);
    } catch (\Exception $e) {
        DB::rollback();
        Log::info('vehicle image name save issue: ', [$e->getMessage()]);
        return 'false';
    }
}

Hope this will help others who are going to upload multiple images with react native

Comments

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.