The question is published on by Tutorial Guruji team.
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.
Answer
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 }