empty result when getting data from mongodb with mongoose and node js - node.js

I'm trying to fetch all my documents from a collection in my MongoDb DB but I can't do it. I have absolutely no error but it just returns an empty array in my console.
Model :
import mongoose from "mongoose";
const websiteSchema = mongoose.Schema({
id: {type: String},
name: {type: String, required: true},
url: {type: String, required: true},
note: {type: Number, required: true}
});
export default mongoose.model("Website", websiteSchema);
File in which I want to use the data :
import express from 'express';
import Website from '../models/website.js';
const routerWebsiteList = express.Router();
routerWebsiteList.get('/website-list', async function(req, res, next) {
try {
const websitesToCrawl = await Website.find({});
console.log(websitesToCrawl);
} catch (error) {
res.status(500).json({message : "An error occured"});
}
})
export default routerWebsiteList;
All I get in my console is [].
My data in my database seems good too :

Accully everything looking fine maybe you can use
require for import files
const name = require('name')
and for the export file :
module.exports = routerWebsiteList
after that be sure you connected your database correct like this
async function database() {
await mongoose
.connect(process.env.DATABASE_URL)
.then(() => {
console.log("Database Coonected");
})
.catch((err) => {
console.log(err);
});
}
database()
Last detail is you don't need to put id on mongoose schema just remove it and finally change your model like this
const mongoose = require("mongoose");
const websiteSchema = mongoose.Schema({
name: {type: String, required: true},
url: {type: String, required: true},
note: {type: Number, required: true}
});
const Website = mongoose.model("Website", websiteSchema);
module.exports = Website
I hope that will be helpful. If you will be stuck somewhere feel free to type here again.

I finally found what was the problem. The mongoose Schema was looking in a wrong collection named "websites". All I had to do was to specified the collection name in my model as following : ("websitesToCrawl" is the collection name)
export default mongoose.model("Website", websiteSchema, "websitesToCrawl");

Related

How do I use MongoDB data with D3 and Node?

Using Node, Express, Mongoose, and MongoDB, I'm trying to send a GET request to MongoDB and then use the data as an object for a D3 graph. I have the code for the graph in a separate js file. How do I send the data to that file?
Here are the basic Schemas I'm using:
var hikeSessionSchema = new mongoose.Schema({
hike_name: {type: String, required: true},
hike_date: {type: String, required: true},
mileage: {type: Number, required: true},
duration: {type: String, required: true},
elevation_gain: {type: Number, required: true},
city: {type: String, required: true},
location: {type: String, required: true},
notes: String
})
var hikerSchema = new mongoose.Schema({
username: {type: String, required: true},
log: [hikeSessionSchema]
})
var HikeSession = mongoose.model('HikeSession', hikeSessionSchema)
var Hiker = mongoose.model('Hiker', hikerSchema)
So I want to find the user by ID, then get an array of the user's HikeSessions. And I want to move that data to a js doc to make a d3 graph (I've already made the d3 app on CodePen but connected it to Google Sheets before).
I think the GET request should be something like this, but I don't know what to do with the result. The path will probably change:
app.get('/:id', (req, res) => {
const id = req.params.id;
Hiker.findById(id)
.then(result => {
//What goes here?
})
.catch(err => {
console.log(err);
})
}
After I get the data into the d3 doc, I'm not sure what challenges I'll run into with rendering it.
Step 1:
Define and export your d3_generator(input) function in d3.js:
const d3_generator = (input) => {
/// (Your logic)
}
module.exports = { d3_generator };
Step 2
Import d3_generator function from d3.js in your controller and use it after you got result from MongoDB:
const { d3_generator } = require('./d3');
...
app.get('/:id', (req, res) => {
const id = req.params.id;
Hiker.findById(id)
.then(result => {
let generated_d3 = d3_generator(result.log);
})
.catch(err => {
console.log(err);
})
}

Mongoose Type has no properties in common with type 'DeepPartial<Document>'

I have some trouble to do an easy thing with mongoose but I get stuck I don't know why.
I have this error Type '{ time: any; value: any; applianceId: any; }' has no properties in common with type 'DeepPartial<Document>'.
Here you can find my schema :
import * as mongoose from 'mongoose';
const applianceDataSchema = new mongoose.Schema({
applianceId: {type: mongoose.Schema.Types.ObjectId, required: true},
time: {type: Number, required: true},
value: {type: Number, required: true},
});
const ApplianceDataModel = mongoose.model('relationalApplianceData', applianceDataSchema);
export { ApplianceDataModel }
my insert code :
const appliance = model.appliances.find(a => a.name == data.appliance); // I find the correct appliance here
const doc = {
time: data.time,
value: data.value,
applianceId: appliance._id // I use the objectId here
};
const applianceDataModel = new ApplianceDataModel(doc); // Error here
I don't know what is wrong, I would like to use the objectId object to reference my appliance from my data.
Can you help me ?
the reason for this error applianceId is required and appliance._id will be undefined because you have to wait for model.appliances.find( ..... )
// add async to the callback function for your endpoint
app.post('/your_url', async (req,res)=>{
const appliance = await model.appliances.find(a => a.name == data.appliance);
if(!appliance) res.status(400).send({error:'appliance not found'});
console.log(appliance._id); // should console the _id
const doc = {
time: data.time,
value: data.value,
applianceId: appliance._id
};
const applianceDataModel = new ApplianceDataModel(doc);
await applianceDataModel.save();
res.send({message:'Appliance has been saved'}
});

Mongoose findByIdAndUpdate

I trying to edit and update a form using mongoose. The code seems fine to me, but it doesn't work. I have tried so many ways but the updated version is still the same, I uses a put route to send the form, when I output req.body.studentInfo to the console, it is correct, but the update remains the same. Please help
This is my schema
var mongoose = require("mongoose");
var uniqueValidator = require('mongoose-unique-validator');
var passportLocalMongoose = require("passport-local-mongoose");
var mongoose = require("mongoose");
var UserSchema = new mongoose.Schema({
studentInfo: {
first_name: String,
middle_name: String,
last_name: String,
street: String,
town: String,
city: String,
region: String,
country: String,
studentId: String,
day: Number,
month: String,
year: Number,
},
username: {type: String, required:true, unique:true},
passport: String
});
UserSchema.plugin(uniqueValidator);
UserSchema.plugin(passportLocalMongoose);
module.exports = mongoose.model("StudentInfo", UserSchema);
This is my App.js
app.put('/:id', function(req,res){
StudentInfo.findByIdAndUpdate(req.params.id, {$set: req.body.studentInfo}, function(err, updated){
console.log(req.params.id);
console.log(req.body.studentInfo);
if(err) {
console.log(err);
}
else {
res.redirect('/' + req.params.id);
}
});
});
The studentInfo is an object that contains the names of each variables in my form which I name was studentInfo[name of variable]. Please help
It should be specified that mongoose should return the updated document - by default it returns the original (this is also the behavior of mongodb). I think that if the code gets changed to this:
StudentInfo.findByIdAndUpdate(req.params.id, {$set: req.body.studentInfo}, { new: true }, function(err, updated){
...
});
you will receive the updated document in the callback.
As #Denny mentioned in his answer, mongoose will not return the updated document in the callback until you pass {new : true } option.
For Details and available options check findByIdAndUpdate Docs

Mongoose pre-save hook fires, but does not persist data

I am encountering a problem where my Mongoose pre.save() hook is firing, but the attribute does not get saved to the database. I have been searching for a long time without finding an answer.I found this thread, and the behaviour I am experiencing is very similiar, but OP's problem is related to the context of this, whereas I seem to have a different problem.
Here is my models.js:
'use strict';
const mongoose = require("mongoose");
const slugify = require("slugify");
let Schema = mongoose.Schema;
let BlogPostSchema = new Schema({
title: {
type: String,
required: true
},
createdAt: {type: Date, default: Date.now},
updatedAt: {type: Date, default: Date.now},
author: String,
post: {
type: String,
required: true
}
});
BlogPostSchema.pre('save', function(next) {
this.slug = slugify(this.title);
console.log(this.slug);
next();
});
// Passed to templates to generate url with slug.
BlogPostSchema.virtual("url").get(function() {
console.log(this.slug);
console.log(this.id);
return this.slug + "/" + this.id;
});
BlogPostSchema.set("toObject", {getters: true});
let BlogPost = mongoose.model("BlogPost", BlogPostSchema);
module.exports.BlogPost = BlogPost;
And here is the relevant lines in the router file index.js:
const express = require('express');
const router = express.Router();
const BlogPost = require("../models").BlogPost;
// Route for accepting new blog post
router.post("/new-blog-post", (req, res, next) => {
let blogPost = new BlogPost(req.body);
blogPost.save((err, blogPost) => {
if(err) return next(err);
res.status(201);
res.json(blogPost);
});
});
I am able to save the blog post to the database, and my console.log's correctly prints out the slug to the console. However, the this.slug in the pre-save hook does not get persisted in the database.
Can anybody see what the problem is here? Thank you so much in advance.
Mongoose will act according to the schema you defined.
Currently, your schema does not contain s filed named slug.
You should add a slug field to your schema.
Changing your current schema to something like this should work:
let BlogPostSchema = new Schema({
slug: String,
title: {
type: String,
required: true
},
createdAt: {type: Date, default: Date.now},
updatedAt: {type: Date, default: Date.now},
author: String,
post: {
type: String,
required: true
}
});

Retrieve Array in Subdocument MongoDB

I have a Users model structure somewhat like this:
const userSchema = new mongoose.Schema({
email: { type: String, unique: true },
password: String,
todosDo: [models.Do.schema],
}
And the child "Do" schema somewhat like this (in a different file):
const doSchema = new mongoose.Schema({
name: {type: String, default : ''},
user: {type: mongoose.Schema.ObjectId, ref: 'User'},
createdAt: {type : Date, default : Date.now}
});
And I'm trying to figure out how to retrieve the todosDo array for the signed in user. This is what I've got so far:
// Get all "Do" todos from DB
// Experimenting to find todos from certain user
User.findById(req.user.id, function(err, user){
if(err){
console.log(err);
} else {
doTodos = user.todosDo, // this obviously doesn't work, just an idea of what I was going for
console.log(doTodos);
finished();
}
});
Am I referencing the child/parent wrong or am I just not retrieving the array right? Any help is greatly appreciated!
As far I guess you may want to edit as raw js objects so you need to use lean() function. without using lean() function user is mongoose object so you can't modify it.
can try this one:
User.findById(req.user.id)
.lean()
.exec(function (err, user) {
if(err){
console.log(err);
return res.status(400).send({msg:'Error occurred'});
}
if(!user) {
return res.status(400).send({msg:'User Not found'});
}
doTodos = user.todosDo;
console.log(user.todosDo); // check original todos
console.log(doTodos);
return res.status(200).send({doTodos : doTodos }); // return doTodos
});
and to refer child schema in parent schema from different model you can access a Model's schema via its schema property.
say in doSchema.js file
const doSchema = new mongoose.Schema({
name: {type: String, default : ''},
user: {type: mongoose.Schema.ObjectId, ref: 'User'},
createdAt: {type : Date, default : Date.now}
});
module.exports = mongoose.model( 'DoSchema', doSchema );
in user.js file
var DoModel = require('./doSchema');// exact path
const userSchema = new mongoose.Schema({
email: { type: String, unique: true },
password: String,
todosDo: [DoModel.schema],
}
Thanks for your help everybody! My problem was that I needed to push all the newly created todos in the post route to todosDo, so then I could retrieve them at the get route. Everything's working now!

Resources