A.S.J
A.S.J

Reputation: 637

ReactJS multiple file upload and axios post: Uncaught (in promise) SyntaxError:

In my ReactJS application, the user can upload multiple images, which are saved to the filesystem and whose links I then fetch from a database (to which I saved them beforehand). This works fine as long as the user only uploads one image, but I need to be able to upload a large amount of images at the same time.

When I do that, I always get the following error:

Uncaught (in promise) SyntaxError: Unexpected token P in JSON at position 0
    at Main.js:278
    at <anonymous>

This is how I post/fetch the data:

handleUpload (event) {
    var _this = this;
    var files = event.target.files;

    const data = new FormData();

    for (var i=0; i<files.length; i++) {
        data.append("icons", files[i]);  
    }

    axios.post('/newicons', data)
    .then(function (response) {
            console.log(response);
            _this.props.handleUpload()
        })
        .catch(function (error) {
            console.log(error);
        });
}

handleUpload() {
    fetch('/icons')
        .then(res => res.json())
        .then(icons => this.setState({icons}))
}

I also tried using promises, like so:

addIcons (event) {
  var _this = this;
  var files = event.target.files;

    const data = new FormData();

    for (var i=0; i<files.length; i++) {
        data.append("icons", files[i]);  
    }

    axios.post('/newicons', data)
    .then(function (response) {
            console.log(response);
            _this.props.handleUpload()
        })
        .catch(function (error) {
            console.log(error);
        });
}

handleIconUpload (event) {
    return Promise.all([this.addIcons(event)])
        .then(this.props.handleUpload())
        .catch(err => console.log('There was an error:' + err))
}

But this gives me this error:

 Unhandled Rejection (SyntaxError): Unexpected token P in JSON at position 0 (anonymous function)
 275 | 
 276 | handleUpload() {
 277 |  fetch('/fetchicons')
 > 278 |        .then(res => res.json())
 279 |      .then(fetchedicons => this.setState({fetchedicons}, () => 
this.setIcons()))
 280 | }`

I'm not really sure how to fix this.

When the user opens the page I want to fetch the images which have already been uploaded. Once the user uploads more images, I want to update the images which are displayed on the website.

To my understanding, the code above (not the one with the promise) posts the pictures and once it's successful, it calls this.props.handleUpload() and fetches the images once again, so I don't really understand why it's not working with several images.

What I want to know is: What am I doing wrong in my attempts to fix this problem and how to I solve it?

Edit: this is my /newicons-route:

const storage = multer.diskStorage({
    destination: (req, file, cb) => {
        cb(null, "./client/src/icons");
    },

    filename: (req, file, cb) => {
        const newFilename = `${uuidv4()}${path.extname(file.originalname)}`;
        cb(null, newFilename);
    },
})

const upload = multer({ storage: storage });

router.post("/", upload.array('iconupload'), (req,res) => {
    for (var i=0; i<req.files.length; i++) {
        var newIcon = new Icons();
        newIcon.icons = req.files[i].path;
        newIcon.save(function (err) {
        if(err)
            res.send(err);
        res.send("Entry added successfully!");
    });
    }

    console.log(filelist);
});

Upvotes: 1

Views: 3374

Answers (1)

Dyo
Dyo

Reputation: 4464

You're sending a server response when iterating in the images array, you have to move the send outside of the loop :

router.post("/", upload.array('iconupload'), (req,res) => {
    try {
       req.files.forEach((image) => {
           var newIcon = new Icons();
           newIcon.icons = image.path;
           newIcon.save(function (err) {
              if(err) throw err;
           });
       });
       res.send("Entry added successfully!");
    } catch (e) {
       res.send(e)
    }
});

Upvotes: 1

Related Questions