Nuxt Upload multiple files toS3

1.2k Views Asked by At

I am trying to figure out how to upload multiple files to my S3 bucket but can't seem to figure it out. I am running a Nuxt.js app with express api. I am just testing out 1 or 2 files to upload, but get a 500 response with the error: Missing credentials in config, if using AWS_CONFIG_FILE, set AWS_SDK_LOAD_CONFIG=1.

My Vue Template: /pages/add.vue

<template>
  <v-col cols="12">
    <h2 class="display-1 font-weight-light mb-5">Add Photos</h2>
    <v-form
      ref="uploadForm"
      v-model="valid"
      enctype="multipart/form-data"
      lazy-validation
      @submit.prevent="submitFiles"
    >
      <v-row>
        <v-col cols="12" sm="6">
          <v-file-input
            v-model="photos"
            :counter="30"
            :rules="uploadRules"
            accept="image/png, image/jpeg"
            show-size
            multiple
            label="Click to upload photos"
          />
        </v-col>
        <v-col cols="12" sm="6">
          <v-btn :loading="loading" color="primary" @click="submitFiles()">
            Upload
          </v-btn>
        </v-col>
      </v-row>
    </v-form>
  </v-col>
</template>

<script>
export default {
  layout: 'admin',
  data: () => ({
    photos: [],
    uploadRules: [(v) => (v && v.length <= 30) || 'No more than 30 files'],
    valid: true,
    loading: false
  }),
  methods: {
    submitFiles() {
      if (this.$refs.uploadForm.validate()) {
        this.loading = true
        const formData = new FormData()
        const Form = this

        for (let i = 0; i < this.photos.length; i++) {
          const file = this.photos[i]
          formData.append(`photos['${i}']`, file)
        }

        this.$axios
          .post('/photos/upload', formData, {
            headers: {
              'Content-Type': 'multipart/form-data'
            }
          })
          .then((res) => {
            console.log('success')
            console.log(res)
          })
          .catch((error) => {
            console.log('fail')
            console.log(error)
          })
          .finally(() => {
            Form.loading = false
            Form.photos = []
          })
      }
    }
  }
}
</script>

my upload file: /utils/upload.js

const aws = require('aws-sdk')
const multer = require('multer')
const multerS3 = require('multer-s3')
const s3 = new aws.S3()

aws.config.update({
  apiVersion: '2006-03-01',
  accessKeyId: process.env.AWS_KEY,
  secretAccessKey: process.env.AWS_SECRET,
  region: process.env.AWS_REGION_APP
})

const upload = multer({
  storage: multerS3({
    s3,
    bucket: process.env.BUCKET,
    acl: 'public-read',
    metadata: (req, file, cb) => {
      cb(null, { fieldName: file.fieldname })
    },
    key: (req, file, cb) => {
      cb(null, Date.now().toString())
    }
  })
})

module.exports = upload

My Express api: /api/photos.js

const express = require('express')
const app = express()
const bodyParser = require('body-parser')
app.use(bodyParser.json())

const upload = require('../utils/upload')

// Upload photos
app.post('/upload', upload.array('photos', 3), (req, res) => {
    res.send('Successfully uploaded ' + req.files.length + ' files!')
})

module.exports = app
1

There are 1 best solutions below

0
On

I'm still not exactly sure why, but after I installed aws-cli to test my credentials, it worked.

I also updated part of the code in the add.vue file from:

for (let i = 0; i < this.photos.length; i++) {
   const file = this.photos[i]
   formData.append(`photos['${i}']`, file)
}

to:

for (let i = 0; i < this.photos.length; i++) {
   formData.append(`photos`, this.photos[i])
}