0

I'm attempting to upload a file using the multer npm module, with Express.js, jQuery and AJAX. According to Postman, my API works fine when uploading a file. My problem is on the jQuery side.

Backend

var express = require('express');
var path = require('path');
var router = express.Router();
var Post = require('../models/posts');
var checkPost = require('../middleware/check-post');
var multer = require('multer');         //Module to upload files to the database

/**
 * Specification variable to place the file in the './uploads/' directory and what to call them
 */
var storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, './uploads/posts');
  },
  filename: function (req, file, cb) {
    cb(null, new Date().toISOString() + file.originalname)      //new Date().toISOString() converts the current date to a string
  }
});

/**
 * Specification variable to filter for the file types that can be uploaded to posts
 */
const fileFilter = function (req, file, cb) {
  var fileTypes = ['image/jpeg', 'image/png', 'application/pdf', 'application/msword',                           //File types that are allowed
    'application/vnd.openxmlformats-officedocument.wordprocessingml.document',                                      //.jpeg, .png, .pdf, .doc, .docx, .ppt, .pptx
    'application/vnd.ms-powerpoint', 'application/vnd.openxmlformats-officedocument.presentationml.presentation']

  if (fileTypes.indexOf(file.mimetype) > -1) {     //Checks to see if file.mimetype is in the fileFilter array
    cb(null, true);
  } else {
    cb(null, false);
  }
};

/**
 * Adds the specification variables to 'multer' and saves them in the upload variable
 */
var upload = multer({
  storage: storage,
  limits: {
    fileSize: 1024 * 1024 * 10       //Sets the file size limit to 10MB
  },
  fileFilter: fileFilter
});

/**
 * Adds posts to our database
 */
router.post('/addPost', upload.single('post_file'), function (req, res, next) {
  var post = new Post(req.body);

  if (req.file) {
    post.post_file = req.file.path
  }

  post.save(function (err, savedPost) {
    if (err)
      res.status(500).json(err);

    res.status(201).json({
      status: "Successfully added the post",
      id: savedPost._id
    });
  });
});

Frontend (HTML)

<div class="container-fluid">
  <div class="col-xs-offset-2">
    <h1>Create a Post</h1>
  </div>
</div>

<div class="container-fluid">
  <div class="well col-xs-10 col-xs-offset-1">
    <div class="row col-xs-10 col-xs-offset-1">
      <form class="form-horizontal" role="form" id="postForm">
        <div class="row">
          <div class="form-group">
            <div class="col-xs-12">
              <textarea class="form-control required" style="min-width: 100%" rows="1" placeholder="Title" id="inputPostTitle"></textarea>
            </div>
          </div>
        </div>
        <!---Title--->

        <div class="row">
          <div class="form-group">
            <div class="col-xs-12">
              <textarea class="form-control required" style="min-width: 100%" rows="5" placeholder="Desciption" id="inputPostDesc"></textarea>
            </div>
          </div>
        </div>
        <!---Description--->

        <div class="row">
          <div class="form-group">
            <div class="col-xs-3">
              <label class="btn btn-info">
                <span class="glyphicon glyphicon-paperclip">
                  <input type="file" id="inputPostFile" hidden>
                </span> Attach Files
              </label>
            </div>
            <div class="col-xs-7">
            </div>
            <div class="col-xs-2">
              <a href="#" data-toggle="popover" data-placement="bottom" data-content="Please enter your post...">
                <button type="text" class="btn btn-warning btn-lg">Post</button>
              </a>
            </div>
          </div>
        </div>
        <!---Buttons--->

      </form>
    </div>
  </div>
</div>

<script src="/javascripts/create-post.js"></script>

Frontend (jQuery)

$(document).ready(function () {
  /**
   * Event handler for when the user submits a post
   */
  $("#postForm").submit(function (event) {
    event.preventDefault();

    var path = window.location.pathname;
    var fields = path.split("/");
    var module = fields[4];                           //Module code
    var route = path.replace("/createPost", "");      //Route for the POST request
    var file = document.getElementById("inputPostFile").files[0];
    var formData = new FormData();
    formData.append("inputPostFile", file);
    console.log(formData);

    $.ajax({
      url: route + '/addPost',
      type: 'POST',
      data: formData,
      contentType: false,
      processData: false,
      successs: function() {
        console.log('success');
      },
      error: function() {
        console.log('error');
      }
    })
  });
});

The console returns a POST 500 Internal Error. How do I amend this? And can I attach more form data with the file?

1 Answer 1

1

In your ajax you specify the file as inputPostFile but on the server side its post_file.
Change it to post_file in the ajax

formData.append("post_file", file);

You can add any data with the same append function.
Also, you can pass the form as an argument to the FormData constructor to add all the fields in the form so you don't have to use append.
If you do that however you'll have to add name attributes to the form fields.

Sign up to request clarification or add additional context in comments.

1 Comment

Sorry I haven't logged in for a while, but thanks for the response.

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.