mongoose model.findOne is not a function (Node.js | React Native) - javascript

So, I am making an app with react native and i am trying to use mongoose and mongoDB for my DataBase but i am running into this error: OD.findOne is not a function, OD being my model file.
const mongoose = require("mongoose");
const newOrgData = new mongoose.Schema({
author: String,
PW: String,
name: String,
Good: Number,
Bad: Number,
Medium: Number
});
module.exports = new mongoose.model("OrganizationData", newOrgData)
My DB.js file where i do the function:
const OD = require("../config/OrgData");
export async function GetStats(txt, point) {
await OD.findOne({
name: txt
}, (err, data) => {
if (txt.length <= 3) return Alert.alert("Please use a valid organization, the name needs to be over three characters long.");
if (err) console.log(err);
if (!data) {
Alert.alert("Sorry, that organization does not exist.");
return;
} else {
if (point == 1) {
data.Good++;
data.save();
} else {
if (point == 2) {
data.bad++;
data.save();
} else {
if (point == 3) {
data.medium++;
data.save();
} else {
if (point == 0) {
return Alert.alert("Please choose how you feel about this organization today.");
} else {
Alert.alert("Succes, thank you for your interest.");
}
}
}
}
}
});
}
My server.js file where i connect to mongoose:
const Config = require("./config/config.json");
const mongoose = require("mongoose");
mongoose.connect("mongodb+srv://BlueSyntax:" + Config.Mongo_C_PW +
"#org-qjoao.mongodb.net/" + Config.DB_Name + "?retryWrites=true&w=majority", {
useMongoClient: true
});
How should i fix this?

You have to omit new keyword when exporting the model. The correct form:
module.exports = mongoose.model("OrganizationData", newOrgData)

Related

TypeError deleting a file with gridfs mongoose and node.js

I am developing an application that allows uploading and downloading music.
I can upload files, send them to the client... however, I have problems when it comes to deleting a bucket file...
I'am using "mongoose": "^6.2.1".
My controller, where podcastId is a ObjectId:
const connection = require('../database')
const mongoose = require('mongoose')
const Users = require('../models/Users')
const PodcastInfo = require('../models/PodcastInfo')
ctrPod.deletePodcast = async (req, res, next) => {
try {
const id = req.params.idPodInfo
const info = await PodcastInfo.findById(id)
const { userId, podcastId } = info
const gridFsBucket = new mongoose.mongo.GridFSBucket(connection, {
bucketName: 'podcasts',
});
gridFsBucket.delete(podcastId, (err) => {
console.log(err)
})
.
.
.
I get this error:
TypeError: Cannot use 'in' operator to search for 'client' in undefined
at getTopology
The problem appears here, \node_modules\mongodb\lib\utils.js:363:23) :
function getTopology(provider) {
if (`topology` in provider && provider.topology) {
return provider.topology;
}
else if ('client' in provider.s && provider.s.client.topology) {
return provider.s.client.topology;
}
else if ('db' in provider.s && provider.s.db.s.client.topology) {
return provider.s.db.s.client.topology;
}
throw new error_1.MongoNotConnectedError('MongoClient must be connected to perform this operation');
}
////////////////////////
delete(id, callback) {
return (0, utils_1.executeLegacyOperation)((0, utils_1.getTopology)(this.s.db), _delete, [this, id, callback], {
skipSessions: true
});
}
/////////////////////////////////////
What am I doing wrong?
I think the problem lies here:
const gridFsBucket = new mongoose.mongo.GridFSBucket(connection, {
bucketName: 'podcasts',
});
new mongoose.mongo.GridFSBucket(db,{bucketName}) takes in a db not a connection. Try:
const gridFsBucket = new mongoose.mongo.GridFSBucket(connection.db, {
bucketName: 'podcasts',
});

How to move the code to set ut DB and collection out from my file and just requre it?

So, let's say I have this code that works perfectly.
const {
Database
} = require("arangojs");
var db = new Database({
url: "http://localhost:8529"
});
const database_name = "cool_database";
db.useBasicAuth("username", "password123");
db.listDatabases()
.then(names => {
if (names.indexOf(database_name) > -1) {
db.useDatabase(database_name);
db.get();
} else {
db.createDatabase(database_name)
.then(() => {
db.useDatabase(database_name);
db.collection("my-collection").create();
});
}
});
const collection = db.collection("my-collection");
const getJobFromQueue = () => {
return db.query({
query: "FOR el IN ##collection FILTER DATE_TIMESTAMP(el.email.sendAfter) < DATE_NOW() AND el.status != 'processed' AND el.status != 'failed' SORT el.email.sendAfter LIMIT 1 RETURN el",
bindVars: {
"#collection": "my-collection"
}
})
.then(cursor => cursor.all());
}
But I want to move the top code out to another file and just require db and collection, how do I make that work? Have been struggling to make it work for too long now.
const {
db,
collection
} = require("./db");
const getJobFromQueue = () => {
return db.query({
query: "FOR el IN ##collection FILTER DATE_TIMESTAMP(el.email.sendAfter) < DATE_NOW() AND el.status != 'processed' AND el.status != 'failed' SORT el.email.sendAfter LIMIT 1 RETURN el",
bindVars: {
"#collection": "my-collection"
}
})
.then(cursor => cursor.all());
}
just do exactly what you proposed. move the upper part of your code to db.js and expose dband collection using exports:
db.js:
const {
Database
} = require("arangojs");
var db = new Database({
url: "http://localhost:8529"
});
const database_name = "cool_database";
db.useBasicAuth("username", "password123");
db.listDatabases()
.then(names => {
if (names.indexOf(database_name) > -1) {
db.useDatabase(database_name);
db.get();
} else {
db.createDatabase(database_name)
.then(() => {
db.useDatabase(database_name);
db.collection("my-collection").create();
});
}
});
exports.collection = db.collection("my-collection");
exports.db = db;
index.js:
const {
db,
collection
} = require("./db");
const getJobFromQueue = () => {
return db.query({
query: "FOR el IN ##collection FILTER DATE_TIMESTAMP(el.email.sendAfter) < DATE_NOW() AND el.status != 'processed' AND el.status != 'failed' SORT el.email.sendAfter LIMIT 1 RETURN el",
bindVars: {
"#collection": "my-collection"
}
})
.then(cursor => cursor.all());
}
WARNING:
keep in mind, there is a potential race condition in your code. you may end up using db and collection, before they hat been initialized.

Mongoose validate length of array in schema

I want to create a schema, with arrays for names of participants at an event, I make the list of participants by doing so:
quizPart:[{
type:String,
}]
How can I validate that the length of this array is either zero (no participants at this event) or 2, and not 1 (it is a two people per team event). I want to return an error message that I can handle with ValidationError
I am adding data to this schema like so:
var school = new School();
school.quizPart=req.body.quiz;
where req.body.quiz = ["name1","name2"] or ['','']
and then, if only 1 field has a string value, I want to parse an error to the repsonse body like so:
function handleValidationError(err, body) {
for (field in err.errors) {
switch (err.errors[field].path) {
case "quizPart":
body["quizPartError"] = err.errors[field].message;
break;
}}}
This is a working example of what I mean to say.
Write a pre('update') mongoose hook and inspect the $set object if the quizParts field has length 0 or 2 or not.
index.js
const mongoose = require('mongoose');
const test = require('./test');
mongoose.connect('mongodb://localhost:27017/test2', {useNewUrlParser: true});
mongoose.set('debug',true);
const db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function() {
// we're connected!
});
(async() => {
try {
const testUpdate = test();
const updateQuery = {
$set: {
quizPart: [
{
type: 'Type 1'
},
{
type: 'Type 2'
}
]
}
};
const updateResult = await testUpdate.update({}, updateQuery).exec();
} catch(err) {
console.error(err);
}
})();
test.js
const mongoose = require('mongoose');
const { Schema } = mongoose;
module.exports = function() {
const testSchema = new Schema({
quizPart: [
{
type: String,
}
]
},
{
collection: 'test',
timestamps: true
});
testSchema.pre('update', function(next) {
const update = this._update.$set;
if (update.length === 0 || update.length === 2) {
return next();
}
else {
return next(new Error('Cannot have length 1!'));
}
});
return mongoose.model('test', testSchema);
};
Made the field:
quizPart:[{
type:String,
}],
And then verified the field by:
schoolSchema.path('quizPart').validate((list)=>{
alNumRegex= /^[a-z0-9]+$/i
return list[0]!=="" && list[1]!=="" || alNumRegex.test(list[0]) && alNumRegex.test(list[1]);
},'Please Register atleast two participants for quiz.');

Search Operators in Sequelize

I wanted to display all of the data which have gains of greater than 1. But I seem to encounter problems on running the request on my postman with the url of :
http://localhost:3000/api/betHistory/winners
I get the result of:
Executing (default): SELECT `id`, `user_id`, `type`, `league_id`, `team_id`, `amount`, `gains`, `ratio`, `match_id`, `created_at`, `updated_at`, `updatedAt` FROM `bets` AS `bets` WHERE `bets`.`gains` = false;
which should be 'gains' '>' '1'
This is my bet.js
router.get('/winners', async (req, res) => {
try {
const data = req.params.gains;
const bets = await BetRepository.getWinnersBets(data > 1);
res.json(bets);
} catch (error) {
res.status(400).send('No data found');
}
});
This is my BaseRepistory.js
findAll(fields) {
const options = {};
if (!!fields && fields) {
options.attributes = fields;
}
return this.model.findAll(options);
}
And this is my BetRepository.js
const BaseRepository = require('../../../shared/repository/BaseRepository');
const Bet = require('../models/Bet');
const Op = require('sequelize').Op;
class BetRepository extends BaseRepository {
constructor(model) {
super(model);
}
getWinnersBets(gains, fields) {
const options = {
where: { gains }
};
if (!!fields && fields) {
options.attributes = fields;
}
return this.model.findAll(options);
}
}
module.exports = new BetRepository(Bet);
Any ideas on how to work with this? TYIA.
When you do getWinnersBets(data > 1);, you are not passing the expression data > 1 to getWinnersBets, you are passing getWinnersBets(true) or getWinnersBets(false) to it, so in your query you are actually querying
'gains' '=' 'true'
and not
'gains' '>' '1'
I don't know the API of model.findAll so I can't give you a pointer on how to pass that expression to findAll
I have solved this problem by putting an operator on my getWinnersBets
getWinnersBets(fields) {
const options = {
where: {
gains: {
[Op.gte]: 1
}
}
};
if (!!fields && fields) {
options.attributes = fields;
}
return this.model.findAll(options);
}
and removed the > 1 line on my const bets = await BetRepository.getWinnersBets(data > 1)

Node not seeing module

I have the following compiled typescript class in file: User.js
"use strict";
var mongo = require('mongoose');
var User = (function () {
function User(data) {
this.Name = data.name;
this.City = data.city;
this.State = data.state;
}
User.prototype.nameUpperCase = function () {
return this.Name.toUpperCase();
};
return User;
}());
exports.User = User;
var schema = new mongo.Schema({
Name: String,
City: String,
State: String
});
schema.method('nameUpperCase', User.prototype.nameUpperCase);
var Users = mongo.model('User', schema);
usertest.js contents:
require('User.js'); <-- no matter what I put here
var u1 = new Users({Name: 'Matthew Brown', City:'Austin',State:'TX'});
var u2 = new Users({Name: 'Jonathan Andrews', City:'Georgetown',State:'TX'});
var u3 = new Users({Name: 'Mom(Rose Brown)', City:'Holiday Island',State:'AR'});
var u4 = new Users({Name: 'Ditto(Bill Brown Jr.)', City:'Charlton',State:'MA'});
Users.create(u1,function(err, u1) {
if (err) {
console.log(err);
} else {
console.log("User %s created",u1.Name);
}
});
Users.create(u2,function(err, u2) {
if (err) {
console.log(err);
} else {
console.log("User %s created",u2.Name);
}
});
Users.create(u3,function(err, u3) {
if (err) {
console.log(err);
} else {
console.log("User %s created",u3.Name);
}
});
Users.create(u4,function(err, u4) {
if (err) {
console.log(err);
} else {
console.log("User %s created",u4.Name);
}
});
I have tried everything and i keep getting the error from node saying that it can not find the module 'User' or above, it will say it can not find 'User.js'.
In User.js you are not exporting mongoose User Model
Change
var Users = mongo.model('User', schema);
to
exports.Users = mongo.model('User', schema);
Also in usertest.js, Users not defined anywhere
Change
require('User.js');
to
var Users = require('./User.js').Users; // check for relative path here
Now
can not find 'User.js'
is because you are not setting relative path.
You can refer without relative path to node_modules folder libraries, inbuilt node.js libraries & Global libraries

Categories