3

I want to upload multiple images to the database by using axios in reactjs to send the data from client-side to server-side and handle the image upload with laravel in the server-side. My problem is that whenever i try to handle multiple images at the server-side, it doesn't work.

This is my code.

CLIENT-SIDE (ReactJS)

CONSTRUCTOR:

constructor(props){
        super(props);
        this.state = {
            id: "upload-photo",
            imageArray: [],
            body: '',
            posts: [],
            // image: []
        };
        this.handleSubmit = this.handleSubmit.bind(this);
        this.handleBodyChange = this.handleBodyChange.bind(this);
    }

HanleFileChange:

handleFileChange(e){
        if (e.target.files) {
            const files = Array.from(e.target.files);

            const promises = files.map(file => {
                return (new Promise((resolve, reject) => {
                    const reader = new FileReader();
                    reader.addEventListener('load', (ev) => {
                        resolve(ev.target.result);
                    });
                    reader.addEventListener('error', reject);
                    reader.readAsDataURL(file);
                }))
            });

            Promise.all(promises).then(images => {
                this.setState({
                    imageArray: images
                })
            }, error => { console.error(error); });
        }
        if (this.props.onChange !== undefined) {
            this.props.onChange(e);
        }
    }

HandleSubmitChange:

handleSubmit(e) {
        e.preventDefault();
        // this.postData();
        const formData = new FormData();
        this.state.imageArray.forEach((image_file) => {
             formData.append('file[]', image_file);
        });
        formData.append('body', this.state.body);
        for (let pair of formData.entries()) {
            console.log(pair[0]+ ', ' + pair[1]);
        }
        axios.post('/posts', formData)
            .then(response => {
            this.setState({
                posts: [response.data]
            })
        });
        this.setState({
            body: ''
        });
    }

SERVER-SIDE (LARAVEL)

public function create(Request $request, Post $post) {
        $data = [];
        if ($request->get('file')) {
            foreach ($request->get('file') as $file) {
                $name = time() . '.' . explode('/', explode(':', substr($file, 0, strpos($file, ';')))[1])[1];
                \Image::make($file)->save(public_path('images/') . $name);
                array_push($data, $name);
            }
        }
        $image = json_encode($data);
        // create post
        $createdPost = $request->user()->posts()->create([
            'body' => $request->body,
            'image' => $image
        ]);
        // return the response
        return response()->json($post->with('user')->find($createdPost->id));
    }

I expect all uploaded images to be saved to the database. Instead, it throws an error: Invalid argument supplied for foreach(). Therefore, if i remove, the foreach() loop and upload only one image, it saves the image successfully. How can I make use of the loop to save multiple images?

UPDATE
This question has been answered in the comments below by @DelenaMalan. I updated the code in this question so that others searching for answers related to this problem can use the code to solve their problem.

4
  • 1
    Just a quick guess: JSON.stringify the files array before appending it to formData Commented Apr 9, 2019 at 16:13
  • 1
    Try this on the frontend side: this.state.imageArray.forEach((image_file) => { formData.append('file[]', image_file); }); Commented Apr 9, 2019 at 16:19
  • Thanks @DelenaMalan. That worked like a charm :) Commented Apr 9, 2019 at 16:43
  • Good to hear @IsraelObanijesu I'll post it as an answer. Commented Apr 10, 2019 at 7:51

1 Answer 1

10

In your frontend side you could use formData.append('file[]', image_file) to add your image files to the file array in the form data, for example:

this.state.imageArray.forEach((image_file) => {
    formData.append('file[]', image_file);
});
Sign up to request clarification or add additional context in comments.

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.