Why isn't my mongoose sort method working? - javascript

All right. So. I have a really basic API running on Node.js. I'm also using MongoDB as a database and I'm using Mongoose to build queries. My problem is that I'm trying to query for a sorted list of data using using the mongoose 'sort' method. For some reason the method isn't working and Node tries to use the Javascript sort method instead. This is my code:
Query handling:
const mongoose = require("mongoose");
const express = require("express");
const Tour = require("../models/tourModel.js");
exports.getAllTours = async (req, res) => {
try {
// eslint-disable-next-line node/no-unsupported-features/es-syntax
const queryObject = { ...req.query };
const excludedFields = ["page", "sort", "limit", "fields"];
excludedFields.forEach((el) => delete queryObject[el]);
let queryStr = JSON.stringify(queryObject);
queryStr = queryStr.replace(/\b(gte|gt|lte|lt)\b/g, (match) => `$${match}`);
let query = await Tour.find(JSON.parse(queryStr));
// query.sort((a, b) => (a[req.query.sort] > b[req.query.sort] ? 1 : -1));
if (req.query.sort) {
query = query.sort(req.query.sort);
}
const tours = await query;
res.status(200).json({
status: "success",
data: { tours },
});
} catch (error) {
res.status(400).json({ status: "failed", message: error.message });
}
};
Router
const tourController = require("../controllers/tourController");
const router = express.Router();
// router.param("id", tourController.checkID);
router
.route("/")
.get(tourController.getAllTours)
.post(tourController.createTour);
router
.route("/:id")
.get(tourController.getTourById)
.patch(tourController.updateTour)
.delete(tourController.deleteTour);
module.exports = router;
Package.json
"name": "natours",
"version": "1.0.0",
"description": "fdsfd",
"main": "index.js",
"scripts": {
"start:dev": "nodemon server.js",
"start:prod": "nodemon server.js NODE_ENV=production "
},
"author": "me",
"license": "ISC",
"dependencies": {
"dotenv": "^8.2.0",
"express": "^4.17.1",
"mongoose": "^5.12.7",
"morgan": "^1.10.0"
},
"devDependencies": {
"eslint": "^7.25.0",
"eslint-config-airbnb": "^18.2.1",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-jsx-a11y": "^6.4.1",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^3.4.0",
"eslint-plugin-react": "^7.23.2",
"prettier": "^2.2.1"
}
}
When I try to query for 127.0.0.1:3000/api/v1/tours?sort=price,
I get a response
{
"status": "failed",
"message": "The comparison function must be either a function or undefined"
}
I'm a real noob in this so does anyone have any ideas what is causing this or how to fix it?

let query = await Tour.find(JSON.parse(queryStr));
This is the result of your query since await executes the query. If you want to store the query, don't use await
let query = Tour.find(JSON.parse(queryStr));
// query.sort((a, b) => (a[req.query.sort] > b[req.query.sort] ? 1 : -1));
if (req.query.sort) {
query = query.sort(req.query.sort);
}
const tours = await query;

Related

Model.create is not a function at seed

I am trying to seed my db and this issue is preventing that. It keeps saying "Inventory.create is not a function
at seed". I am not sure if this is a syntactical issue, a logistical problem or even a dependency issue so please point me in the wrong direction.
The tech stack that I am using is Express, Node.js, Sequelize, PostgreSQL
My files are structured as such:
--script
-seed.js
--server
-api
-db
-Model.js
-index.js
-db.js
-app.js
-index.js
Model.js
const db = require('./db');
const Model = db.define('model', {
name: {
type: Sequelize.STRING,
allowNull: false,
},
total: {
type: Sequelize.FLOAT,
allowNull: false,
},
})
module.export = Model;
index.js
const db = require('./db')
const Inventory = require('./Inventory')
module.exports = {
db,
models: {
Inventory,
},
}
db.js
const Sequelize = require('sequelize')
const pkg = require('../../package.json')
const databaseName = pkg.name + (process.env.NODE_ENV === 'test' ? '-test' : '')
if(process.env.LOGGING === 'true'){
delete config.logging
}
if(process.env.DATABASE_URL){
config.dialectOptions = {
ssl: {
rejectUnauthorized: false
}
};
}
const db = new Sequelize(
process.env.DATABASE_URL || `postgres://localhost:5432/${databaseName}`, {
logging: false,
})
module.exports = db
seed.js
'use strict'
const {db, models: {Model}} = require('../server/db')
async function seed() {
await db.sync({ force: true })
console.log('db synced!')
// Creating Inventory
const stock = await Promise.all([
Model.create({ name: 'First', amount: 200 }),
Model.create({ name: 'Second', amount: 200 }),
])
console.log(`seeded successfully`)
}
async function runSeed() {
console.log('seeding...')
try {
await seed()
} catch (err) {
console.error(err)
process.exitCode = 1
} finally {
console.log('closing db connection')
await db.close()
console.log('db connection closed')
}
}
if (module === require.main) {
runSeed()
}
module.exports = seed
I included this just in case
package.json
{
"name": "ShopifyInventory",
"version": "1.0",
"description": "Simple backend heavy app for inventory management",
"main": "app.js",
"scripts": {
"build": "webpack",
"build:dev": "npm run build -- --watch --mode=development",
"seed": "node script/seed.js",
"start": "node server"
},
"dependencies": {
"axios": "^0.21.1",
"bcrypt": "^5.0.0",
"compression": "^1.7.3",
"express": "^4.18.1",
"history": "^4.9.0",
"jsonwebtoken": "^8.5.1",
"morgan": "^1.9.1",
"pg": "^8.7.3",
"pg-hstore": "^2.3.4",
"react": "^18.1.0",
"react-dom": "^18.1.0",
"react-router-dom": "^6.3.0",
"sequelize": "^6.19.2"
},
"author": "Galilior :)",
"devDependencies": {
"#babel/core": "^7.17.12",
"#babel/preset-react": "^7.17.12",
"babel-loader": "^8.2.5",
"webpack": "^5.72.1",
"webpack-cli": "^4.9.2"
}
}

DiscordJS interactionCreate and messageCreate not working

I know this and this post both have similar titles but the solution to both is not working for me.
As you can see in my code below I've used Intents.FLAGS.GUILD_MESSAGES to create the client variable but it doesn't give any output in my console when I do the /ping command that I made. /ping however is available in when typing "/" in chat.
const { clientId, token, testGuildId } = require('./config.json');
const Discord = require('discord.js');
const fs = require('fs');
const { REST } = require('#discordjs/rest');
const { Routes } = require('discord-api-types/v9');
const client = new Discord.Client({
intents: [
Discord.Intents.FLAGS.GUILDS,
Discord.Intents.FLAGS.GUILD_MESSAGES,
Discord.Intents.FLAGS.DIRECT_MESSAGES,
],
});
const commandFiles = fs.readdirSync(`./Commands/commandScripts`).filter(file => file.endsWith(".js"));
//for
const commandsArray = [];
client.commandsArray = new Discord.Collection();
for (const file of commandFiles){
const newCommand = require(`./Commands/commandScripts/${file}`);
commandsArray.push(newCommand.data.toJSON());
client.commandsArray.set(newCommand.data.name, newCommand);
}
client.once('ready', async () => {
const rest = new REST({
version: "9"
}).setToken(token);
(async () => {
try {
if(process.env.ENV === "production"){
await rest.put(Routes.applicationCommands(clientId), {
body: commandsArray,
});
console.log("Successfully registered commands globally.");
} else {
var temp = await rest.put(Routes.applicationGuildCommands(clientId, testGuildId), {
body: commandsArray,
});
console.log(temp);
console.log("Successfully registered commands locally.");
}
} catch (err) {
if(err) console.error(err);
}
})();
console.log(`[${time}] *** Bot Is Ready On Discord!`);
});
client.on('interactionCreate', async interaction => {
console.log(interaction);
});
client.on("messageCreate", (message) => {
console.log(message.content);
})
client.login(token);
My package.json:
{
"name": "excavator",
"version": "1.0.0",
"description": "",
"main": "index.js",
"dependencies": {
"#discordjs/builders": "^0.12.0",
"#discordjs/opus": "^0.3.3",
"#discordjs/rest": "^0.3.0",
"axios": "^0.21.1",
"discord-api-types": "^0.27.3",
"discord.js": "^12.5.3",
"ffmpeg-static": "^4.2.7",
"fs": "0.0.1-security",
"mongoose": "^5.13.14",
"path": "^0.12.7",
"simple-youtube-api": "^5.2.1",
"yt-search": "^2.5.1",
"ytdl-core": "^4.4.5",
"ytdl-core-discord": "^1.2.5"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "ExcanatorGames",
"license": "ISC"
}
Figured out the problem. I needed to uninstall discord.js and reinstall discord.js

Rest api issue after deploying react app to heoku

So basically with my app i have react js and node js. Everything works fine but I have a section of the web app that makes a post request to the node backend to get data related to getting an array of items through the ebay api. This worked fine during development but when I tried to do the same thing after deployment, I get a 404 error
Response {type: "basic", url: "https://udabasili.herokuapp.com/api/ebay", redirected: false, status: 404, ok: false, …}
The client link is https://udabasili.herokuapp.com/
The server link is https://ud-portfolio-app.herokuapp.com/
I even used postman to send a post request to the node domain deployed on heroku and it works, so the problem seems to be from the react js app
The app is a quite big but basically i have the node and react on two different domains with have the static.json linking the node serveri have deployed already to react js using proxy
The important sections of the app involved :
STATIC.JSON
{
"root":"build/",
"routes":{
"/**":"index.html"
},
"proxies":{
"/api/":{
"origin":"https://ud-portfolio-app.herokuapp.com/"
}
}
}
NODE.JS
const express = require("express");
const app = express()
const path = require("path")
const Ebay = require('ebay-node-api');
const cors = require("cors")
const bodyParser = require("body-parser");
const PORT = process.env.PORT || 8081;
let access_token = '';
let ebay = new Ebay({
clientID: '******************',
clientSecret: '*******************',
body: {
grant_type: 'client_credentials',
scope: 'https://api.ebay.com/oauth/api_scope'
}
});
app.use(cors());
app.use(bodyParser.urlencoded({extended:true}));
app.use(bodyParser.json());
// An api endpoint that returns a short list of items
app.post('/api/ebay', (req,res) => {
const item = req.body.itemName;
ebay.findItemsByKeywords({
keywords: `${item} movie`,
}).then((data) => {
res.json(data[0].searchResult[0].item);
}, (error) => {
console.log(error);
});
});
app.listen(PORT);
REST API SECTION
At this section I fetch the two apis . The youtube one work but the ebay has the 404 error
function fetchProducts(name) {
const itemName = name;
const ebayApi = fetch("/api/ebay",
{
method: "POST",
cache: "no-cache",
headers:{
"Content-Type": "application/json"
},
body:JSON.stringify({itemName:itemName})
}
);
const youtubeApi = fetch(`https://www.googleapis.com/youtube/v3/search?part=snippet&q=${name}%20movie%20trailer&key=**************`);
return (dispatch) => {
Promise.all([ebayApi, youtubeApi])
.then( values => Promise.all(values.map(value =>{
console.log(value);
return value.json()})
))
.then(res => {
const youtube = `https://www.youtube.com/embed/${res[1].items[0].id.videoId}?autoplay=1&showinfo=0&rel=0`;
return (res[0], res[1].items[0].id.videoId)
})
.catch((error) => {
console.log(error);
});
};
}
export default fetchProducts;
CLIENT PACKAGE.JSON
{
"name": "client",
"version": "0.1.0",
"proxy": "http://localhost:8081",
"private": true,
"dependencies": {
"babel-eslint": "^10.0.3",
"d3": "^5.12.0",
"ebay-node-api": "^2.7.2",
"flag-icon-css": "^3.4.5",
"font-awesome": "^4.7.0",
"node-sass": "^4.13.0",
"prop-types": "^15.7.2",
"react": "^16.11.0",
"react-dom": "^16.11.0",
"react-redux": "^7.1.1",
"react-router-dom": "^5.1.2",
"react-scripts": "3.2.0",
"react-transition-group": "^4.3.0",
"redux": "^4.0.4",
"redux-persist": "^6.0.0",
"redux-thunk": "^2.3.0",
"topojson-client": "^3.0.1",
"youtube-api-search": "^0.0.5"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"lint": "eslint --ext .js --ext .jsx ."
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"eslint": "^6.6.0",
"eslint-config-airbnb": "^18.0.1",
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-jsx-a11y": "^6.2.3",
"eslint-plugin-react": "^7.16.0",
"eslint-plugin-react-hooks": "^1.7.0"
}
}

mongodb connection timeout error with mongoose and nodejs

I desperately need some help.I am trying to upload large file(8 GB) to gridfs using mongoose and nodeJS. But as the file is very large it takes some time to upload. And after a while I get the following error:
home/user/FileUpload/node_modules/mongodb/lib/utils.js:98
process.nextTick(function() { throw err; });
^
MongoError: connection 0 to 127.0.0.1:27017 timed out
at Function.MongoError.create (/home/user/FileUpload/node_modules/mongodb-core/lib/error.js:29:11)
at Socket.<anonymous> (/home/user/FileUpload/node_modules/mongodb-core/lib/connection/connection.js:186:20)
at Object.onceWrapper (events.js:314:30)
at emitNone (events.js:105:13)
at Socket.emit (events.js:207:7)
at Socket._onTimeout (net.js:402:8)
at ontimeout (timers.js:488:11)
at tryOnTimeout (timers.js:323:5)
at Timer.listOnTimeout (timers.js:283:5)
I have tried to resolve this by increasing connectTimeoutMS but the error still persist. I am using MongoDB 3.4.5 mongoose 4.8.4 nodejs 8.1.4 and npm 5.0.3.
Following is app.js:
var mongoose = require('mongoose');
var schema = mongoose.schema;
mongoose.connect('mongodb://127.0.0.1/gridFS'),{
server: {
socketOptions: {
socketTimeoutMS: 3000000,
connectionTimeoutMS: 3000000,
keepAlive:3000000
}
},
replset: {
socketOptions: {
keepAlive: 3000000,
connectTimeoutMS: 3000000
}
}
};
var conn = mongoose.connection;
var path = require('path');
var Grid = require('gridfs-stream');
var fs = require('fs');
var videoPath = path.join(__dirname, 'readFrom/bio seq test1.txt');
Grid.mongo = mongoose.mongo;
conn.once('open', function(){
console.log('- connection open -');
var gfs = Grid(conn.db);
var writestream = gfs.createWriteStream({
filename: 'bio seq test 1'
});
fs.createReadStream(videoPath).pipe(writestream);
writestream.on('close', function(file){
console.log(file.filename + 'Written to DB');
});
});
Following is package.json file:
{
"name": "file-upload-gridfs",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo '' && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"body-parser": "^1.16.1",
"cookie-parser": "^1.4.3",
"express": "^4.14.1",
"gridfs-stream": "^1.1.1",
"mongoose": "^4.8.4",
"morgan": "^1.8.2",
"multer": "1.3.0",
"multer-gridfs-storage": "1.0.0",
"path.join": "^1.0.0",
"serve-favicon": "^2.4.3"
}
}
Ok. I figured out the problem using this really helpful discussion.The default socket connection time for MongoDB is 30 seconds. If any query/operation takes longer than this the connection is aborted and connection timeout error occurs.
With this change I was able to upload a 32GB file to GridFS without any interruption.
https://github.com/Automattic/mongoose/issues/4789
I was passing the timeout parameter in following way.
server: {
socketOptions: {
socketTimeoutMS: 3000000,
connectionTimeoutMS: 3000000,
keepAlive:3000000
}
},
replset: {
socketOptions: {
keepAlive: 3000000,
connectTimeoutMS: 3000000
}
}
};
But it needs to be set in the following way:
const serverOptions = {
poolSize: 100,
socketOptions: {
socketTimeoutMS: 6000000
}
};
mongoose.createConnection(dbpath, {
server: serverOptions,
replset: serverOptions //if you are using replication
});
In my case I have used localhost.
const serverOptions = {
poolsize:100 ,
socketOptions:{
socketTimeoutMS: 6000000
}
};
var mongodbUri = 'mongodb://localhost:27017/gridFS';
mongoose.connect(mongodbUri, {
server: serverOptions
});
Hope this will help anyone with similar issue.

Babel 6 doesn't transpile my code

This is my code
require('babel-register')
require('babel-polyfill')
const Koa = require('koa');
const app = new Koa();
// logger
app.use(async (ctx, next) => {
const start = new Date;
await next();
const ms = new Date - start;
console.log(`${ctx.method} ${ctx.url} - ${ms}ms`);
});
// response
app.use(ctx => {
ctx.body = 'Hello World';
});
app.listen(3000);
An example taken by Koa v2.0 that use async/await. Unfortunately it doesn't work. I get the following error:
app.use(async (ctx, next) => {
SyntaxError: Unexpected token (
Here is the package.json.
{
"name": "app",
"version": "0.0.1",
"scripts": {
"start": "node index"
},
"dependencies": {
"koa": "^2.0.0-alpha.3"
},
"devDependencies": {
"babel-plugin-transform-async-to-generator": "^6.3.13",
"babel-polyfill": "^6.3.14",
"babel-preset-stage-0": "^6.3.13",
"babel-register": "^6.3.13",
"eslint": "^1.10.3"
}
}
Here is my .babelrc
{
"presets": ["stage-0"],
"plugins": ["transform-async-to-generator"]
}
Solved. It needed to include es2015 preset as well and move hook to another file

Categories

Resources