0

I want to upload file to mongodb with graphql resolver. In server.js I have this help function to store file, which is exported to use it in my resolver. The function is basing on what I found here: https://github.com/jaydenseric/graphql-upload/issues/8), but now some things have changed in graphql. For example destructurising file object. I don't know what should be found at path variable and how should I use this createReadStream(function which was destructurized from file).

const mongoose = require('mongoose');
const Grid = require('gridfs-stream');
const fs = require('fs');

//...

// Connect to Mongo
mongoose
  .connect(process.env.mongoURI, {
    useNewUrlParser: true,
    useCreateIndex: true,
    useUnifiedTopology: true,
    useFindAndModify: false
  }) // Adding new mongo url parser
  .then(() => console.log('MongoDB Connected...'))
  .catch(err => console.log(err));




const storeFile = async (upload) => {
   const { filename, createReadStream, mimetype } = await upload.then(result => result);

   const bucket = new mongoose.mongo.GridFSBucket(mongoose.connection.db, { bucketName: 'files' });

   const uploadStream = bucket.openUploadStream(filename, {
     contentType: mimetype
   });
   createReadStream()
     .pipe(uploadStream)
     .on('error', console.log('error'))
     .on('finish', console.log('finish'));
 }

module.exports = { storeFile }
//...

My resolver(here it's minimal version, because now I want only to upload file into my database. In one of my tries, it even created fs.files and fs.chunks collections, but without a data):

Mutation: {
    uploadFile: async (_, { file }) => {
      console.log(file);
      const fileId = await storeFile(file);

      return true;
     
    }
  }

I have this error now:

Unhandled Rejection (Error): GraphQL error: The "listener" argument must be of type function. Received undefined

and in terminal I have printed 'error'(like in pipe.on('error', console.log('error') statement )

And I can upload only small files( max 60 kb), all larger just don't upload, but errors are showing on all tries.

Wiktor Kujawa
  • 595
  • 4
  • 21

1 Answers1

2

Ok, I managed to solve it.

resolver mutation:

const { storeFile } = require('../../server');
//...

uploadFile: async (_, { file }) => {
      const fileId = await storeFile(file).then(result => result);

      return true;
// later I will return something more and create some object etc.
    }

supporting function from server.js

 const storeFile = async (upload) => {
    const { filename, createReadStream, mimetype } = await upload.then(result => result);

    const bucket = new mongoose.mongo.GridFSBucket(mongoose.connection.db, { bucketName: 'files' });
    
    const uploadStream = bucket.openUploadStream(filename, {
      contentType: mimetype
    });
    return new Promise((resolve, reject) => {
      createReadStream()
        .pipe(uploadStream)
        .on('error', reject)
        .on('finish', () => {
            resolve(uploadStream.id)
        })
    })
  }

  module.exports = { storeFile }
Wiktor Kujawa
  • 595
  • 4
  • 21