2

I'm using Vue with NodeJs, Vuetify and Express. I load user's file with the Vuetify's component:

<v-file-input
v-model="documentFile.value"
:error-messages="documentFile.errors"
accept="application/pdf"
/>

Then I want to pass the file (that is stored in this.documentFile.value) to my backend, so it will upload it to the Drive. I pass the data using Vue Recourse:

var params = {
    "data":                 this.data.value
    "score":                this.score.value
    //"document_file":        this.documentFile.value,
    "comments":             this.comments.value
};

Vue.http.put('http://localhost:8081/api/new-document', {params: params}).then(
  response => {
      console.log("Sent data");
  }, response => {
      console.error(response);
  }
);

In my NodeJS backend I have:

router.put('/new-document', function(request, response) {
  console.log("New Document");
  console.log(request.query);

  // Upload file to drive
  const oauth2Client = new google.auth.OAuth2(
    CLIENT_ID,
    CLIENT_SECRET,
    REDIRECT_URI
  );
  response.status(200).send({});
});

How can I pass the file from the client to the backend?

EDIT: If I uncomment document_file, and try to print request.query, it prints:

{
  data: { age: '27', name: 'robert' },
  comments: 'comment',
  "score": 89
}

For some reason, it ignores the document_file.

The code in my server.js:

const cors       = require("cors");
const express    = require("express");
const bodyParser = require("body-parser");

const routes     = require('./routes');

const path = __dirname + '/../public/';

console.log("STARTED");

const app = express();

app.use(express.static(path));

var corsOptions = {
  origin: "http://localhost:8080"
};



app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

// map requests to routes
app.use('/api', routes);


// set port, listen for requests
const PORT = process.env.PORT || 8081;
app.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}.`);
});
2
  • What is the result ofconsole.log(request.query); // >? Commented Jan 29, 2022 at 8:23
  • @RotikenGisa If I uncomment the document_file line, it does not pass it to the request.query. But it pass all the others.
    – vesii
    Commented Jan 29, 2022 at 21:57

1 Answer 1

0

To pass the file from the client to the backend, use the new FormData() object.

In your case you can do something like:

var params = new FormData();
params.append('data', this.data.value);
params.append('score', this.score.value);
params.append('document_file', this.documentFile.value)
params.append('comments', this.comments.value);

Then pass the object either using axios or Vue Recourse as you would like.

axios.put('url', params)

EDIT

You can use multer to upload your files either locally or to the cloud. In your case, you can upload to GoogleStorage

const multer  = require('multer')

// You can start off by testing local uploads
const upload = multer({ dest: 'uploads/' })

// then use this to upload to Google Storage
const multerGoogleStorage = require('multer-google-storage')

const uploadHandler = multer({
  storage: multerGoogleStorage.storageEngine({
    autoRetry: true,
    bucket: '<your_storage_bucket_name>',
    projectId: '<your_project_ID>',
    keyFilename: '<your_path_to_key_file>',
    filename: (req, file, cb) => {
      cb(null, `/<some_prefix_of_choice>/${Date.now()}_${file.originalname}`)
    }
  })
})

Upload the file either to local or Google Cloud

// local uploads (destination projectRoot/uploads)
router.put('/new-document', upload.single('document_file'), async (request, response) => {});
// or GoogleStorage
router.put('/new-document', uploadHandler.single('document_file'), async (request, response) => {});

Multiple files can also be uploaded

app.put('/new-document', upload.array('document_files', 12), function (req, res, next) {
  // req.files is array of `photos` files
  // req.body will contain the text fields, if there were any
})

The document file(s) can then be accessible on the Express server using

request.file

You can the upload the file. The other form objects can also be accessible through request.body e.g.

request.body.data
4
  • I tried both with axios and VueResouse. I get request.query={}, request.body={} and request.document_file=undefined. Why is that?
    – vesii
    Commented Jan 30, 2022 at 23:27
  • 1. Does your Express app use app.use(express.json()) or const bodyParser = require('body-parser'); app.use(bodyParser())? 2. You access the document_file through request.file not request.document_file Commented Jan 31, 2022 at 6:08
  • I use const bodyParser = require('body-parser'); app.use(bodyParser()); app.use('/api', routes);. Also, tried request.file but it's undefined as well (what if I need to pass two files?)
    – vesii
    Commented Jan 31, 2022 at 8:38
  • @vesii I have updated the answer using multer Commented Jan 31, 2022 at 12:38

Not the answer you're looking for? Browse other questions tagged or ask your own question.