Code Monkey home page Code Monkey logo

mongoose-gridfs's Introduction

mongoose-gridfs

Build Status Dependencies Status Coverage Status GitHub License

Commitizen Friendly code style: prettier Code Style npm version

mongoose gridfs on top of new gridfs api

Note!: Only compatible with Mongoose >= 6.0.7+

Note!: Ensure mongoose connection before use

Requirements

Installation

$ npm install --save mongoose mongoose-gridfs

Usage

import { createReadStream } from 'fs';
import { createModel } from 'mongoose-gridfs';

// use default bucket
const Attachment = createModel();

// or create custom bucket with custom options
const Attachment = createModel({
    modelName: 'Attachment',
    connection: connection
});

// write file to gridfs
const readStream = createReadStream('sample.txt');
const options = ({ filename: 'sample.txt', contentType: 'text/plain' });
Attachment.write(options, readStream, (error, file) => {
  //=> {_id: ..., filename: ..., ...}
});

// read larger file
const readStream = Attachment.read({ _id });

// read smaller file
Attachment.read({ _id }, (error, buffer) => { ... });

// remove file and its content
Attachment.unlink({ _id }, (error) => { ... });

Read Documentation

Literature Reviewed

Testing

  • Clone this repository

  • Install all development dependencies

npm install
  • Run example
npm run dev
  • Then run test
npm test

Contribute

It will be nice, if you open an issue first so that we can know what is going on, then, fork this repo and push in your ideas. Do not forget to add a bit of test(s) of what value you adding.

License

The MIT License (MIT)

Copyright (c) CodeTanzania & Contributors

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

mongoose-gridfs's People

Contributors

360disrupt avatar cbratschi avatar dependabot[bot] avatar felixfurtmayr avatar frguthmann avatar jakesjews avatar lkho avatar lykmapipo avatar pytkin avatar v4l3r10 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

mongoose-gridfs's Issues

Add user ObjectId reference to attachment Schema

I've been tweaking and trying many different things to include a user property to an attachment but had no luck so far.

Is it possible to modify/extend the current schema for attachments so that I can relate it to the user?

Question: How to Update the File Buffer?

The two cases writing a new file and updating the metadata are pretty straight forward. But what's the way to update the file buffer.

const fileBuffer = file.buffer;
delete file.buffer;       
const readStream = new Readable();
readStream.push(fileBuffer);
readStream.push(null);

Writing a new file:

Attachment.write(file, readStream, callback)

But as soon as the _id already is in the DB it throws an err. My current approach is to unlink the file first but it looks smelly.

Attachment.unlink({_id: file._id}, (err) => {
    if (err) {return callback(err)}
    Attachment.write(file, readStream, callback)
});

I know I can update the metadata with Attachment.updateOne but is there a solution to update the actual file buffer?

Didn't find anything here regarding updates:
https://docs.mongodb.com/manual/core/gridfs/

Using generic mongoose, not the real one

Hi, AFAIK some statics and methods refers to mongoose and not the real db, in my case i've several connections with mongoose.Mongoose, and when tried to unlink or use another function referred to mongoose it throws an error.

You just have to change all mongoose for this inside all methods and statics.

regards.

readById metadata content-type

I am trying to do a search and return in addition to the image the metadata as the content-type but I do not find this functionality.

ensure mongoose connection

Hello,
Is it really necessary to ensure mongoose connection before use? I tried removing this lines #L31 and it worked perfectly.

what inconvenience did you find without this lines?

thanks

File with ID <xxxxxx> not opened for writing

Hey there!

I'm using gridfs with mongoose and running into this error:

"name":"MongoError","message":"file with id 5adfc7a99b0e190f7aa9cd0a not opened for writing","driver":true

with this code:

db.User.findById(obj.api_token, function (err, user) {
        db.Attachment.readById(user.picture.id, function (error, buffer) {
            if(buffer)
            {
                callback(null, buffer);
            }
            else
            {
                callback(error, null);
            }
        })
    });

I made sure the file itself exists in the database and is available.
Any idea how this happened?

Kind regards
Nop0x

报错: mongoose.pluralize is not a function

TypeError: mongoose.pluralize is not a function
at exports.toCollectionName.modelName (/Users/Seven/work/cis-ecosystem/cis-service-gridfs/node_modules/@lykmapipo/mongoose-common/index.js:340:31)

at createModel (/Users/Seven/work/cis-ecosystem/cis-service-gridfs/node_modules/mongoose-gridfs/lib/bucket.js:634:16)

Error installing npm-package via proxy

Hi.

I,ve faced a problem while installing via cntlm proxy.

Error message: "fatal: unable to access 'https://github.com/lykmapipo/gridfs-stream.git/': Unknown SSL protocol error in connection to github.com:443"

In "package-lock.json" file at line #538 I see this text:

"gridfs-stream": {
"version": "git+https://github.com/lykmapipo/gridfs-stream.git#dd3c07d5c33264d1cbab9fc53a682a64e095bec4",
"requires": {
"flushwritable": "1.0.0"

Is it correct? It has no "resolved" key and URL in "version" key.

get file properties after readById

Hi I try to get the properties like the filename and mimetype after a readById but as I receive a Buffer I don't know how to get them.

Here is my code

//instantiate mongoose-gridfs
    var gridfs = require('mongoose-gridfs')({
        collection:'files',
        model:'Files',
        mongooseConnection: mongoose.connection
    });

    Files = gridfs.model;
Files.readById(<fileId>, function(error, buffer){
    if(error) {
        console.log(error);
    }
    console.log(typeof buffer)
    console.log(buffer.property)
//some image modification
        Files.write({
                filename:filename,
                contentType:filetype
            },
            fs.createReadStream(buffer),
            function(error, savedAttachment){
            });
    });
});

mongoose_gridfs__WEBPACK_IMPORTED_MODULE_7__ is not a function after upgrade from 0.5.0 to 1.2.48

When upgrading from version 0.5.0 to 1.2.48 we get the following errors:

  • mongoose_gridfs__WEBPACK_IMPORTED_MODULE_7__ is not a function
    [- DEP_WEBPACK_WATCH_WITHOUT_CALLBACK] DeprecationWarning: A 'callback' argument need to be provided to the 'webpack(options, callback)' function when the 'watch' option is set. There is no way to handle the 'watch' option without a callback.

This is our whole dependency tree:
"dependencies": {
"@angular/animations": "12.1.4",
"@angular/cdk": "12.1.4",
"@angular/common": "12.1.4",
"@angular/compiler": "12.1.4",
"@angular/core": "12.1.4",
"@angular/flex-layout": "12.0.0-beta.34",
"@angular/forms": "12.1.4",
"@angular/material": "12.1.4",
"@angular/material-moment-adapter": "12.0.0",
"@angular/platform-browser": "12.1.4",
"@angular/platform-browser-dynamic": "12.1.4",
"@angular/router": "12.1.4",
"@datorama/akita": "^2.2.1",
"@datorama/akita-ngdevtools": "^3.0.2",
"@fortawesome/fontawesome-pro": "file:.fonts/fontawesome-pro.tar.gz",
"@material-extended/mde": "^3.0.3",
"@nest-middlewares/morgan": "^6.0.0",
"@nestjs/axios": "^0.0.1",
"@nestjs/common": "^8.0.6",
"@nestjs/config": "^1.0.1",
"@nestjs/core": "8.0.6",
"@nestjs/jwt": "^8.0.0",
"@nestjs/mongoose": "^8.0.0",
"@nestjs/passport": "^8.0.1",
"@nestjs/platform-express": "8.0.6",
"@nestjs/platform-socket.io": "^8.0.6",
"@nestjs/websockets": "^8.0.6",
"@ngneat/hotkeys": "^1.1.1",
"@ngneat/until-destroy": "^8.0.2",
"@ngrx/effects": "12.2.0",
"@ngrx/entity": "12.2.0",
"@ngrx/store": "12.2.0",
"@ngrx/store-devtools": "12.2.0",
"@ngx-pwa/local-storage": "10.0.1",
"@ngx-translate/core": "13.0.0",
"@ngx-translate/http-loader": "6.0.0",
"@sentry/browser": "^6.2.1",
"@sentry/integrations": "^6.2.1",
"@sentry/node": "^6.2.1",
"@sentry/tracing": "^6.2.1",
"@stomp/stompjs": "^5.4.4",
"@swimlane/ngx-graph": "^7.2.0",
"app-root-path": "^3.0.0",
"chart.js": "^2.9.3",
"class-transformer": "^0.2.3",
"class-validator": "^0.11.1",
"color": "^3.1.2",
"colors": "^1.4.0",
"core-js": "^3.8.3",
"express-fileupload": "^1.1.6",
"graphql-ld": "^1.1.0",
"graphql-ld-sparqlendpoint": "^1.0.1",
"hammerjs": "^2.0.8",
"helmet": "^3.22.0",
"jexl": "^2.2.2",
"jsonld": "^3.1.1",
"jwt-decode": "^2.2.0",
"ldapts": "^2.2.1",
"lodash": "^4.17.19",
"mongo-gridfs": "^1.1.0",
"mongodb": "^3.6.5",
"mongoose": "~5.13.5",
"mongoose-gridfs": "^0.5.0",
"morgan": "^1.10.0",
"multer-gridfs-storage": "^5.0.0",
"nest-winston": "^1.3.5",
"ng-mocks": "10.1.2",
"ng2-charts": "2.4.0",
"ng4-click-outside": "^1.0.1",
"ngx-color-picker": "10.0.1",
"ngx-cookie-service": "10.0.1",
"ngx-drag-drop": "^2.0.0",
"ngx-filter-pipe": "^2.1.2",
"ngx-infinite-scroll": "9.0.0",
"ngx-json-viewer": "^2.4.0",
"ngx-let-directive": "^1.0.1",
"ngx-markdown": "10.1.1",
"ngx-order-pipe": "2.1.0",
"ngx-pagination": "5.0.0",
"ngx-permissions": "8.0.0",
"ngx-schema-form": "2.4.8",
"ngx-socket-io": "^3.3.1",
"ngx-uploader": "10.0.0",
"node-fetch": "^2.6.1",
"object-hash": "^2.1.1",
"passport": "^0.4.1",
"passport-http-bearer": "^1.0.1",
"passport-jwt": "^4.0.0",
"passport-local": "^1.0.0",
"reflect-metadata": "^0.1.13",
"rxjs": "7.3.0",
"sass-loader": "^8.0.2",
"semver": "^7.3.2",
"sockjs-client": "^1.5.0",
"sparqljs": "^3.0.1",
"svg.draggable.js": "^2.2.2",
"svg.draw.js": "^2.0.4",
"svg.js": "^2.7.1",
"svg.panzoom.js": "^1.2.3",
"svg.resize.js": "^1.4.3",
"svg.select.js": "^3.0.1",
"tslib": "^2.0.0",
"uuid": "^7.0.3",
"winston": "^3.3.2",
"ws": "^7.3.1",
"z-schema": "^4.2.2",
"zone.js": "0.11.4"
}

Stream variant doesn't work

readById works well with the callback version, that provides a buffer but the stream version just errors out and doesn't work. Does it work for you?

Below is the error I get:

TypeError: Cannot read property 'on' of undefined
      at GridReadStream.Readable.pipe (_stream_readable.js:585:7)
      at router.get (test/src/index.js:120:79)
      at <anonymous>
      at process._tickDomainCallback (internal/process/next_tick.js:228:7)

The id for the file seems to be correct.

[Request] Functionnality

Do you think it would be possible to add a readByFileName function to this module? Great work though, makes the code way easier to read.

You can only read by ID

At the moment you can only read by ID, even if you use the read function, it grabs the _id from the object you pass to it and uses the readById method. Is it possible to read by metadata also or do you plan it in the future?

 var bucketfile = new Bucketfile({
    _id: fileid,
    metadata: { 
        bucket: bucketid
    }
 });

 var stream = bucketfile.read();
 stream.on('data', fn) ....`

Passing base64 data coming as multi-part form data directly to Attachment.write

I'm trying to directly write the file to mongo which comes as binary data from a Form.

` const options = ({ filename: 'Test.png', contentType: 'image/png' });
        Attachment.write(options, req.body.file, (error, file) => {  // req.body.file is having binary data
            
            console.log(error, file);

        });`

is it possible? I don't want to store the file on the server, instead directly write it to mongo. Please guide me in the right direction.

Usage with Typescript

Currently there is no Typescript definition file available. So the usage with Typescript (and type safety) is not possible.

As the exported/created model just is typed as a mongoose model the methods which are additionally added from mongoose-gridfs are not available.

Cannot write using Gridfs model

node.js: "8.4.0"
mongoose: "4.12.1"
mongoose-gridfs: "0.2.0"
gridfs-stream: "1.1.1"
mongodb: "2.2.31"
mongodb-core: "2.1.15"

Cannot write to GridFs using Gridfs Model.

Exception:

node_modules/mongodb/lib/gridfs/grid_store.js:130
  this.readPreference = this.options.readPreference || db.options.readPreference || ReadPreference.PRIMARY;
                                                                 ^

TypeError: Cannot read property 'readPreference' of null
    at new GridStore (node_modules/mongodb/lib/gridfs/grid_store.js:130:66)
    at new GridWriteStream (node_modules/gridfs-stream/lib/writestream.js:64:16)
    at Grid.createWriteStream (node_modules/gridfs-stream/lib/index.js:42:10)
    at GridFSStorage.write (node_modules/mongoose-gridfs/lib/storage.js:127:40)
    at model.GridFSSchema.methods.write (node_modules/mongoose-gridfs/lib/schema.js:75:16)
    at Function.GridFSSchema.statics.write (node_modules/mongoose-gridfs/lib/schema.js:164:14)
    at Object.<anonymous> (index.js:17:6)
    at Module._compile (module.js:573:30)
    at Object.Module._extensions..js (module.js:584:10)
    at Module.load (module.js:507:32)
    at tryModuleLoad (module.js:470:12)
    at Function.Module._load (module.js:462:3)
    at Function.Module.runMain (module.js:609:10)
    at startup (bootstrap_node.js:158:16)
    at bootstrap_node.js:598:3


new version 0.5.0 can not install

yarn install v1.7.0
[1/5] Validating package.json...
[2/5] Resolving packages...
Couldn't find any versions for "mongoose-gridfs" that matches "^0.5.0"
? Please choose a version of "mongoose-gridfs" from this list: (Use arrow keys)
❯ 0.4.1
0.4.0
0.3.2
0.3.1
0.3.0
0.2.0
0.1.0

"close"-event fired too early?

I have an issue where the close-event is fired too early.

When i do this:

readStream.on('data', (data) => { ... })
readStream.on('close', () => { ... })

and log the output, then my output looks like this:

data on readStream261120 index=56
data on readStream261120 index=57
data on readStream261120 index=58
close on readStream:
data on readStream169924 index=59

In my example my file has exactly 59 chunks.

Is this a known issue?
Please tell me, if you need more information on this or if you can't reproduce this issue.
Thanks in advance

warning GridStore is deprecated

work fine,but warning below:
DeprecationWarning: GridStore is deprecated, and will be removed in a future version. Please use GridFSBucket instead

it throw from your custom gridfs-stream(writestream.js,line 64) package.
can you please fix this warning,thanks!

.write() method returns null for err and file in callback

Hi community,

I'm trying to write a file using the .write() method, But both arguments in the callback return null (err and file).

Attachment.write({ ... }, fileData, (err, file) => { //err and file are both null })

The file I'm passing is a duplex.

All Versions of Mongoose, Mongo, and Node.js are the latest available.

Any help would be appreciated.

Thanks,
Marco

Write Callback not giving a error or success state

I am using a CRON job to fetch 50MB around data from remote server and writing that data to MongoDB server.

The issue with current code is that the console.log('data stream formed'); is executed in writeLargeData method, data is being added to mongo DB server but data added successfully is not coming in logs and due to this the parent promise is never resolved. Could you please suggest what's being done wrong.

const { createModel } = require('mongoose-gridfs');
const mongoose = require('mongoose');
const connection = mongoose.connection;
const Readable = require('stream').Readable;
const cron = require('node-cron');
const axios = require('axios');

const ExampleModel = createModel({
  modelName: 'fs',
  connection: connection,
});

async function addDataToMongo(dataStream) {
  const options = ({filename: 'data.txt', contentType: 'text/plain'});
  return new Promise((res, rej)=>{
    ExampleModel.write(options, dataStream, (error, file) => {
      if (error) {
        console.log('error', error);
        rej(error);
        return;
      }
      res(file._id.toString());
      console.log('data added successfully' + file._id.toString());
    });
  });
}

function getReadableStreamFromString(string) {
  let count = 0;
  const chunkSize = 10000;
  return new Readable({
    read() {
      if (count < string.length) {
        this.push(string.slice(count, count + chunkSize));
        count += chunkSize;
      } else {
        this.push(null);
      }
    }
  });
}

async function writeLargeData() {
  const response = await axios.request({
    url: 'https://abc.com',
    method: 'GET',
  });
  console.log('response fetched');
  const dataStream = getReadableStreamFromString(response);
  console.log('data stream formed');
  await addDataToMongo(dataStream);
    
}

cron.schedule('30 12,18,22 * * *', writeLargeData);

@jakesjews Please suggest what should be done in this case.

Refactoring of the code

@lykmapipo can you please refactor your code into normal practice of creating a separate model file. It will make it easy for one to use it your code.

unlink by filename

Hello, we have this on the readme :

// remove file and its content
Attachment.unlink({ _id }, (error) => { ... });

This in the doc :

Attachment.unlink(_id, (error, unlinked) => {
 //=> {_id: ..., filename: ..., ... }
});

This in the code :

FileSchema.statics.unlink = function unlink(_id, done) {

it should be interesting to have this for alignment with read function :)

Attachment.unlink({ filename }, (error) => { ... });

I may have misunderstood something :) thanks again for the work!

write() callback not working, and connection not closing

I seem to be able to successfully write a file, but have no callback triggered to prove I did it. My code looks roughly like this:

mongoose.connect('mongodb://localhost:27017/niss', { useNewUrlParser: true,  useUnifiedTopology: true });

. . .

    // use default bucket
    const Attachment = createModel({
        modelName: 'files',
        connection: mongoose.connection
    });

    const path = 'C:/foo';
    const theFile = 'OFFICIAL/LETTERS/foo.pdf';

    const readStream = createReadStream(path + theFile);

    const options = ({ filename: theFile, contentType: 'application/pdf' });
    
    await Attachment.write(options, readStream, (error, file) => {
        if (error) console.log(error);
        console.log("Successfully wrote file");
    });

Am I not passing in the connection correctly, to the createModel()?

Thanks,
John

Cannot read property 'collection' of undefined

Hello, I'm using mongoose 5.9.15 with mongoose-gridfs1.2.47. After launch server on node.js I have error:

.../node_modules/mongodb/lib/gridfs-stream/index.js:50
_chunksCollection: db.collection(options.bucketName + '.chunks'),
^

TypeError: Cannot read property 'collection' of undefined
at new GridFSBucket (.../node_modules/mongodb/lib/gridfs-stream/index.js:50:27)
at createBucket (.../node_modules/mongoose-gridfs/lib/bucket.js:590:18)
at createModel .../node_modules/mongoose-gridfs/lib/bucket.js:641:18)
at Object. (.../db/general/index.js:27:20)
at Module._compile (internal/modules/cjs/loader.js:1138:30)

What's happen? How I can resolve this problem?

collection parameter ignored

So what I want to do are 2 Gridfs Collections:
Categories & Profile Pictures

I Insert my files with the following function into the categories bucket:

function insertFile(file, callback) {
    let gridfs = require('mongoose-gridfs')({
        collection: 'categories',
        model: 'Attachment',
        mongooseConnection: db
    });
    //DEBUG
    let Attachment = gridfs.model;

    let filePath = path.join(pathString, file);
    Attachment.write({
            filename: file,
            contentType: 'image/png'
        },
        fs.createReadStream(filePath), function (error, createdFile) {
            if(error)
            {
                callback(error, null);
            }
            else
            {
                callback(null, createdFile);
            }
        });
}

For the profile pictures I use the exact same syntax but with the collection changed:

function insertFile(file, callback) {
    let gridfs = require('mongoose-gridfs')({
        collection: 'profilePictures',
        model: 'Attachment',
        mongooseConnection: db
    });
    let Attachment = gridfs.model;
    const readable = toStream(file.buffer);
    Attachment.write({
            filename: file.originalname,
            contentType: file.mimetype
        },
        readable, function (err, createdFile){
            if(err)
            {
                callback(err, null);
            }
            else
            {
                callback(null, createdFile);
            }
        });
}

However the gridfs system is not recognizing the change and still putting the pictures in the categories bucket.

Is this a possible bug?

createModel not working like intended

I'm trying to populate the images in my product schema. It keeps saying "Cannot read property 'length' of undefined". I think my code has an issue with the Image Model. I don't think I'm using/understanding it correctly. I tried looking at the documentation and I think I'm supposed to use "createModel" instead of "createBucket". Why do I think this? Because I think in order for populate to work correctly I need an Image Model. I try using "createModel" instead of "createBucket" but then I get an error saying "Image.createWriteStream is not a function". I thought if you use "createModel" it returns a GridFSBucket that works as a mongoose model. Am I understanding this wrong? Or is it that once I create a model using "createModel" it starts to act like a mongoose model object and I'll have to use ".create"? Appreciate any help I can get!

const express = require("express");
const path = require("path");
const app = express();
const port = 3000;
const mongoose = require("mongoose");
const bodyParser = require("body-parser")
const multer = require("multer");
const upload = multer({ dest: "mongodb://localhost/test1" });
const Grid = require("gridfs-stream");

//Bring in Models
const Product = require("./models/product");


// this connects to your database
mongoose.set('useNewUrlParser', true);
mongoose.set('useUnifiedTopology', true);
mongoose.connect("mongodb://localhost/test1");
let db = mongoose.connection;

// Check connection
db.once("open", () => {
    console.log("Connected to MongoDB")
});

// Check for DB errors
db.on("error", (err) => {
    console.log(err);
    
});

const { createReadStream } = require("fs");
const { createModel, createBucket } = require("mongoose-gridfs");

let imageSchema = {
    modelName: "Image",
    bucketName: "images",
    connection: db
}

app.use(express.static(path.join(__dirname, "public")));

// view engine is a template library and it implements view functionality
app.set("view engine", "pug");

// LANDING PAGE
app.get("/", (req, res) => {
    res.render("index");
});

app.get("/display", (req, res) => {
    Product.find()
    .populate("images")
    .exec((err, products) => {
        res.render("display-products", {products: products});
    });
    // Product.find({}, (err, products) => {
    //     res.render("display-products", {products: products});
    // });
});

app.get("/upload-image", (req, res) => {
    res.render("image_upload");
});

// Upload image to site
app.post("/upload", upload.single("file"), (req, res) => {
    console.log(req.file, req.body);

    
    let title = req.body.title;
    let description = req.body.description;
    let price = req.body.price;

    let newProduct = { title: title, description: description, price: price};

    // Create New Product in DB
    Product.create(newProduct, (err, product) => {
        if(err){
            console.log(err);
        } else {
            let Image = createModel(imageSchema);
            const filename = req.file.originalname;
            const _id = mongoose.Types.ObjectId();
            let metadata = {
                product: product._id
            }
            // reads the database for filename
            const readStream = createReadStream(req.file.path);
            const writeStream = Image.createWriteStream({ _id, filename, metadata });
            readStream.pipe(writeStream);

            product.images = [_id];
            product.save();
            console.log(product)

            res.redirect("/display");
        }
    });
});

app.listen(port, () => {
    console.log("server started");
})
const mongoose = require("mongoose");
//const Imagesfs = require("image")

let productSchema = mongoose.Schema({
    title: { type: String },
    description: { type: String },
    price: Number,
    images: [{type: mongoose.Schema.Types.ObjectId, ref: "Image"}],
    date: { type: Date, default: Date.now }

})

let Product = module.exports = mongoose.model("Product", productSchema)

Return a promise instead of using a callback

Hi. I would like to know if it'd be possible to return a promise when using the write function instead of having to pass a callback to it.

Instead of:

const ye = this.myModel.write(options, shapeStream, (err, file) => {})

where ye ends up being undefined since myModel.write does not return anything, I would like to do:

const ye = this.myModel.write(options, shapeStream);
ye.then((file) => {}).catch((err) => {});

Is this possible?

unlink() does not check errors and empty results

The following code in schema.js should be changed from:

GridFSSchema.statics.unlinkById =
        GridFSSchema.statics.unlink = function(id, done) {
            this.findById(id).exec(function(error, foundInstance) {
                foundInstance.unlink(done);
            });
        };

To:

GridFSSchema.statics.unlinkById =
        GridFSSchema.statics.unlink = function(id, done) {
            this.findById(id).exec((error, foundInstance) => {
                if (error) {
                     return done(error);
                }

                if (!foundInstance) {
                    return done(new Error('not found'));
                }

                foundInstance.unlink(done);
            });
        };

Currently if the file does not exist in GridFS the whole app will crash.

Issue with Writing Files

The write function returns null for the error and file objects. The file gets saved to the database though.
I looked through your source code and found that changing line 94 of schema.js
from: this.constructor.findById(created._id, done);
to bucket.findById(created._id, done);
fixes the problem.

My Node Version is 10.16.0.

update engine in package.json

Your package is incompatible with nodejs 8.9.x and further version because of the engine part in your package.json, perhaps you could change it with a hat in the start?

hello?js eror

const { createModel } = require('mongoose-gridfs')
error
TypeError: Cannot read property 'Decimal128' of null
at Object. (/Users/-check/node_modules/@lykmapipo/mongoose-common/node_modules/mongoose/lib/types/decimal128.js:13:44)
at Module._compile (internal/modules/cjs/loader.js:999:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
at Module.load (internal/modules/cjs/loader.js:863:32)
at Function.Module._load (internal/modules/cjs/loader.js:708:14)
at Module.require (internal/modules/cjs/loader.js:887:19)
at require (internal/modules/cjs/helpers.js:74:18)
at Object. (/Users/-check/node_modules/@lykmapipo/mongoose-common/node_modules/mongoose/lib/utils.js:10:17)
at Module._compile (internal/modules/cjs/loader.js:999:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
at Module.load (internal/modules/cjs/loader.js:863:32)
at Function.Module._load (internal/modules/cjs/loader.js:708:14)
at Module.require (internal/modules/cjs/loader.js:887:19)
at require (internal/modules/cjs/helpers.js:74:18)
at Object. (/Users/-check/node_modules/@lykmapipo/mongoose-common/lib/index.js:7:15)
at Module._compile (internal/modules/cjs/loader.js:999:30)

not ? not support require?????

Add virtual to schema

Is it possible to modify the attachment schema to add a virtual?
I tried adding an "id" virtual (simply returns this._id). It manages to get the correct id but returns undefined when called.

gridFSbucket.schema.virtual("id").get(function(){
	console.log("Called virtual get on " + this._id); // correct id
	return this._id; // when called i get undefined
});

Problem with connection

Hello, I have a problem with connection and bucket. I create a model with createModel({ connection: myMongooseConnection }) but i have this error

Cannot read property 'collection' of undefined at new GridFSBucket

i found that variable db in bucket.js(line 589) is undefined. Any help?
Thanks.

Callback of write() never called

Hi,
I'm having trouble with the write-callback. My schema/model is as follows:

const mongoose = require('mongoose')

const gridfs = require('mongoose-gridfs')({
  collection: 'attachments',
  model: 'Attachment',
  mongooseConnection: global.mongoConnection1
})

module.exports = global.mongoConnection1.model('Attachment', gridfs.schema)

In another file I use the gridfs-model:

const grifs = require('./gridfs.js')

gridfs.write({
  filename: 'myTestFile.ext',
  contentType: 'application/octet-stream'
}, fs.createReadStream('myTestFile.ext'), console.log)

Unfortunately, I see no output (console.log is never called). But the file is stored in my MongoDB database (I can see the entire data). Any suggestion why the callback of the write() operation is never called?

Cannot read properties of undefined (reading 'prototype') since mongoose 6

/Users/pierrebrisorgueil/Documents/Dev/github/rype/Node/node_modules/mongoose-schema-jsonschema/index.js:20
  Types.Embedded.prototype.jsonSchema = types.mixed_jsonSchema;
                 ^
TypeError: Cannot read properties of undefined (reading 'prototype')
    at moduleFactory (/Users/pierrebrisorgueil/Documents/Dev/github/rype/Node/node_modules/mongoose-schema-jsonschema/index.js:20:18)
    at Object.<anonymous> (/Users/pierrebrisorgueil/Documents/Dev/github/rype/Node/node_modules/@lykmapipo/mongoose-common/index.js:71:38)
    at Module._compile (node:internal/modules/cjs/loader:1101:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Module.require (node:internal/modules/cjs/loader:1005:19)
    at require (node:internal/modules/cjs/helpers:94:18)
    at Object.<anonymous> (/Users/pierrebrisorgueil/Documents/Dev/github/rype/Node/node_modules/mongoose-gridfs/lib/schema.js:6:41)
    at Module._compile (node:internal/modules/cjs/loader:1101:14)

Hello, we've been stuck on this since the mongoose 6 update, despite the mongoose common update 🤔 @lykmapipo

Is it possible to change the GridFSSchema ?

I have a File collection defined from Doctrine ODM examples

_id
name (filename)
mime
type (discriminator)
md5
length
filename (full path)
uploadDate
chunkSize

With the schema that is defined in const, I can't get/change my properties and have to change the schema so adding a way to change the schema could be good

[Discussion] plugin design

I was about to investigate how to make gridfs plugin for mongoose, when i found this.
What do you think about mongoose-gridfs as a plugin? with s usage similar to this:

var mongoose = require('mongoose');
var mongooseGridfs = require('mongoose-gridfs');

var UserSchema = mongoose.Schema({
    Name: {
        type: String,
        required: true
    },
    ProfilePicture: {
        type: mongooseGridfs.File
    }
});

UserSchema.plugin(mongooseGridfs);

var User = mongoose.model('User', UserSchema);

var user = new User();
user.Name = 'John Malkovich';
user.ProfilePicture = myFile; /* Stream | Buffer | String */
user.save(); /*To gridFs*/

user.ProfilePicture.stream(); /* Stream */
user.ProfilePicture.buffer(); /* Buffer */

Although it also makes sense to simply implement this for mongoose, as stated here:
Automattic/mongoose#2631

I think still an interesting approach. One could just plug input from multi-part streams or buffers into the model instance, to later pipe the stream back through a router (if one is using express for example)

var express = require('express')
var multer  = require('multer')
var upload = multer()

var app = express()
//...
app.post('/:userId/profile', upload.single('avatar'), function (req, res, next) {
    req.user.ProfilePicture = req.file.buffer;
});
//...
app.post('/:userId/picture', function (req, res) {
    User.findById(req.params.userId, function(err, user){
        user.ProfilePicture.stream().pipe(res)
    });
});

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.