Udara Herath
Udara Herath

Reputation: 885

React Native images save to php (laravel) server

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?

Upvotes: 1

Views: 1087

Answers (2)

Udara Herath
Udara Herath

Reputation: 885

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

Upvotes: 0

Pavel Lint
Pavel Lint

Reputation: 3537

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

data.append('file', image.uri, 'test.jpg');

Upvotes: 1

Related Questions