linking a GridFS-Stream file to a Schema using Mongoose

I am currently developing an API for my application, utilizing Mongoose, Express, and GridFS-Stream. My aim is to create a proper Schema for the articles that users will generate:

var articleSchema = mongoose.Schema({
    title:String,
    author:String,
    type: String,
    images: {type: Schema.Types.ObjectId, ref: "fs.files"},
    datePublished: { type: Date, default: Date.now },
    content: String
})
var Article = mongoose.model("article", articleSchema, "articles");

I also have set up Grid-FS for handling image uploads by users:

api.post('/file', fileUpload.single("image"), function(req, res) {
var path = req.file.path;
var gridWriteStream = gfs.createWriteStream(path)
    .on('close',function(){
        //remove file on close of mongo connection
        setTimeout(function(){
            fs.unlink(req.file.path);
        },1000);
    })
var readStream = fs.createReadStream(path)
    .on('end',function(){
        res.status(200).json({"id":readStream.id});
        console.log(readStream);
    })
    .on('error',function(){
        res.status(500).send("Something went wrong. :(");
    })
    .pipe(gridWriteStream)

});

The current setup automatically uploads user-chosen images using gridfs-stream, places them in a temporary folder, deletes them upon successful upload to the MongoDB server, and returns the ObjectId in the console. However, we need to link this ID with the articleSchema so that when the article is accessed in the app, the associated image is displayed.

Upon creation/update of an article when the user submits it:

createArticle(event) {
event.preventDefault();
var article = {
  type: this.refs.type.getValue(),
  author: this.refs.author.getValue(),
  title: this.refs.title.getValue(),
  content: this.refs.pm.getContent('html')
};
var image = {
  images: this.refs.imageUpload.state.imageString
};
var id = {_id: this.refs.id.getValue()};
var payload = _.merge(id, article, image);
var newPayload = _.merge(article, image)
if(this.props.params.id){
  superagent.put("http://"+this.context.config.API_SERVER+"/api/v1.0/article/").send(payload).end((err, res) => {
      err ? console.log(err) : console.log(res);
  });
} else {
  superagent.post("http://"+this.context.config.API_SERVER+"/api/v1.0/article").send(newPayload).end((err, res) => {
    err ? console.log(err) : console.log(res);
    this.replaceState(this.getInitialState())
    this.refs.articleForm.reset();
  });
}

In summary, I need to retrieve the ObjectId of the uploaded image from fs.files or fs.chunks and associate it with the schema when the user submits an article. Despite attempting a readstream on submission, I'm struggling to access the ID or filename required for association.

The data is stored in the MongoDB database under fs.files and fs.chunks, but I'm finding it challenging to extract or link it without knowing the specific ObjectId. How can I obtain the objectID from fs.files or fs.chunks to connect it with the schema? And how do I reference these components within the schema for identification?

If further information is necessary or if clarification is required, please let me know as I tend to overlook details. Thank you.

Answer №1

After much trial and error, I managed to find a workaround for my issue. It's not the most elegant solution, but it does the job until I find a more efficient one.

The adjustments in the API took place

res.status(200).send(readStream.id);

instead of

res.status(200).json({"id":readStream.id});

Within my component, I updated the state with the response.body data, specifically setting the id value for the uploaded image. This allowed me to link the image state from my component to the view state, thus establishing a connection between the newly created article and its associated id in the database.

An obstacle arose when there was no clear reference point. To address this, I appended the API URL to the id which made it appear as if referencing a URL img, resulting in the correct rendering of the image.

While I acknowledge that this approach may not be ideal, it is currently functioning adequately. I aim to either refine how I interact with the database or develop a new component dedicated to storing server images similarly to Wordpress in the near future.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Discovering foreign key connections in mongoengine

Here are two models that I am working with. class WebURL(mongoengine.Document): codes = mongoengine.ListField(mongoengine.IntField(required=True), verbose_name='Codes') name = mongoengine.StringField(max_length=255, requir ...

Issue with calling jqPlot function in jQuery causing malfunction

I am perplexed as to why the initial code functions correctly while the second code does not. <a data-role="button" href="#page2" type="button" onClick="drawChart([[["Test1",6],["Test2",5],["Test3",2]]])"> <img src="icons/page2.png" inline style ...

Merge floating and absolute positioning techniques

Creating a calendar exhibiting all events in one div requires precise positioning based on the values of top and height. Let me demonstrate this concept. In the image below, both 6am events are aligned vertically. This alignment issue can be resolved by u ...

Does React include a mechanism for event dispatching and listening?

Recently, I've been exploring the intricacies of the Laravel framework and have been fascinated by its event dispatching and listening system. In the past, I've dabbled with electron which shares similarities with Laravel's system, but in m ...

What is the recommended approach for making API calls?

What is the recommended approach for calling an API? Client(Angularjs) -> Router -> API For example: Client $http.post('/login', data, config).then(successCallback,errorCallback); Express app.post('/login', function(req, res ...

What is the best way to retrieve a specific key from a JavaScript Map containing an array?

I am currently iterating through a two-dimensional array to populate a map. The map is using the [i,j] indices as keys and the corresponding arr[i][j] values as values: const arrMap = new Map() for(let i = 0; i < arr.length; i++){ for(let j = 0 ...

Exploring directory organization in GraphQL Queries using GatsbyJS

In my portfolio, I have organized my work into categories, pieces, and pictures in a cascading order similar to a child-parent relationship. The folder structure reflects this hierarchy, with the main problem being explained in more detail below. Folder s ...

Questioning the way spyOn "halts all execution of a function" is described in the Jasmine documentation (specifically in the section on Spies in version 2.2)

I am struggling to comprehend the last test in the Jasmine 2.2 documentation which showcases the basic usage of Spies. In the beforeEach() section, we initialize bar = null, then we spy on foo.setBar and proceed to call foo.setBar twice. I am puzzled as t ...

Is it permissible to make alterations to npm modules for node.js and then share them publicly?

I have made modifications to a module called scribe.js that I use in my own module, which is published on npm. Instead of using the original module as a dependency for my module, I would like to include my modified version. I am unsure about the legal impl ...

React component: Trouble with React-Bootstrap Collapse

Just started diving into React-Bootstrap and I'm trying to create a collapsible card using the Collapse component. However, it doesn't seem to be working as expected. Any suggestions or tips would be greatly appreciated! Here's my code snipp ...

Having trouble getting the Grid class to work in Tailwind with NextJs, any suggestions on why it might not be

Having some trouble with the grid classes in Tailwind not functioning as expected in my code, even though other classes like mt-10 and flex are working perfectly. I've tried applying flex to the parent container and removing it, but the closest I&apo ...

Using HTML to dynamically alter a row's background color depending on its value

I have a table within an HTML page that I would like to color all rows in red when the first column reaches a specific value. After researching on StackOverflow, I found suggestions to add these two attributes (border-collapse and border-spacing) to my ta ...

Tips for recognizing when an input value has been altered within a series of array inputs

How can I determine if the value of an input has been changed? I am fetching a series of inputs from an AJAX request. Here is an example: For each result of the AJAX request print some <input type="text"> here I attempted to use an ID to detect c ...

The issue of ambiguity in JavaScript base-36 conversion

Currently working on a JavaScript project involving base 36 encoding. Encountered the following issue: parseInt("welcomeback", 36).toString(36) It seems to output "welcomebacg". Confirmed the same result in both Chrome developer's console and Node. ...

What is the best way to stop webpack from generating typescript errors for modules that are not being used?

The directory structure is set up as follows: └── src ├── tsconfig.json ├── core │ ├── [...].ts └── ui ├── [...].tsx └── tsconfig.json Within the frontend, I am importing a limi ...

The AJAX error event $(document).ajaxError does not trigger when a 401 status code

An error handler has been implemented to post messages in case of errors. $(document).ajaxError(function (e, xhr, options) { window.postMessage(....); }); One of the fetch calls is consistently returning a 401 status code. this.fetch = function(ur ...

The requested page on node.js cannot be found

I am having trouble getting my server up and running. There are no logs showing up in node.js When I try to access localhost:5000, I receive an error message saying "cannot GET/" const passport = require('passport'); const GoogleStrategy = requ ...

I am interested in excluding the seconds and milliseconds from my date and time

I currently display my time in the following format: 5:34 PM I only want to show the hour and minute. How can I achieve this? ...

Selectively choose certain attributes to save in mongoose's save() method

After saving a document in mongoose and sending it back to the client, what is the best way to pick or omit certain properties before sending it? How can this be done properly? // blablabla someDoc = await page.save() res.send(someDoc) Simply deleting a p ...

Unable to locate resource for passport authentication middleware

Here is a snippet of code that I am currently working with: passport.use(new LocalStrategy({ usernameField: 'emailAddress', passwordField: 'password', passReqToCallback: true }, function(req,username, password, next) { var re ...