Mongoose saves data twice for one request - javascript

I'm relatively new with mongodb and express and I wish to save data which has been retrieved via an api call, to my database. For some reason my server saves the data twice (creates two documents with same details but different id's) for a single get request and I can't figure out why
const log = console.log;
const express = require('express')
const port = process.env.PORT || 8000
const movieServer = require('./movie-getter')
const { Movie } = require('./model/Movie')
const mongoose = require('mongoose')
mongoose.connect('mongodb://localhost:27017/ConspireView', { useNewUrlParser: true});
const app = express()
app.get('/movie/:name/:year', (req, res) => {
const name = req.params.name
const year = req.params.year
// let movieObject
movieServer.getMovie(name, year).then((result) => {
new Movie({
name: result.title,
year: result.release_date,
poster: result.poster_path,
banner: result.backdrop_path,
numOfDiscussions: 0,
numOfComments: 0,
vote_average: 0
// discussions: null
}).save().then(result => {
res.send(result)
})
}).catch((error) => {
log(error)
})
})
Are there any syntactic errors here?

Related

My http request is sending back a blank map

How do I send a map as a response to an HTTP request? Currently I am sending an array of strings as part of the request. I want to send a nested map along with a bool as a response to a post request. The bool sends find but the map always comes back as empty. I did a bit of research to use the Object.entries method but no dice. Heres the client code:
const { response, request } = require('express');
const express = require('express');
const readline = require('readline/promises');
const app = express();
const port = 3000;
const axios = require('axios');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
if (parsedInput > 0 && parsedInput <= 8) {
let listOfNames = [];
for (let i=0; i<parsedInput; i++) {
let name = await rl.question(`Enter name #${i}\n`);
listOfNames.push(name);
console.log(`Added ${name} to list of players\n`);
}
const serverResponse = axios.post('http://localhost:3000/start', {
params: { names: listOfNames },
}).then(function (response) {
const recievedMap = new Map(Object.entries(response.data.scoreboard));
console.log(recievedMap);
})
.catch(function (error) {
console.log(error);
});
}
Server code:
const express = require('express');
var bodyParser = require('body-parser');
const app = express()
app.use(bodyParser.json());
const port = 3000
var listOfNames = [];
const scoreboard = new Map();
app.post('/start', async (req, res) => {
listOfNames = req.body.params.names;
for(let i = 0; i < listOfNames.length; i++){
scoreboard.set(listOfNames[i],[]);
}
var responseObj = {
gameRunning: true,
scoreboard: JSON.stringify(scoreboard),
};
res.status(200).send(responseObj);
});
app.get('/', function(req, res, next) {
res.send("Welcome to the homepage of bowling");
})
app.listen(port, () => {
console.log('Listening to request on port 3000');
});
Output:
Choose a number:
1)Start a bowling game
2)Exit simulation
1
Ok how many players will there be (MAX: 8 players)
1
Enter name #0
dadada
Added dadada to list of players
{}
EDIT: Axios was sending data fine, however Im having issues accessing it when in my web server. Since I cant access any object, I return nothing. Am I refering to my request.body incorrectly?

Can a POST request be made server side?

I am designing a middleware between the client and the GraphQL API. The idea is to create a route that all client requests go to first /filament. This route then decides whether it can send data back from the cache or to proceed on to /graphql to access the resolvers there to get data from the database. I am using Axios to make my requests but it isn't firing server side. I wanted to ask if this was just an improper way to use Axios or if I am doing it incorrectly.
Server.js
const express = require('express');
const { graphqlHTTP } = require('express-graphql');
const fetch = require("node-fetch");
const redis = require("redis");
const PORT = process.env.PORT || 4000;
// const REDIS_PORT = process.env.REDIS_PORT || 6379;
//Create Redis client on Redis port (optional)
const client = redis.createClient();
const schema = require('./schema');
const bluebird = require('bluebird')
const app = express()
// bluebird.promisifyAll(redis.RedisClient.prototype);
// bluebird.promisifyAll(redis.Multi.prototype);
app.use(express.json())
client.on("error", err => {
console.log("Error " + err);
});
client.on('connect', () => {
console.log('Redis client connected');
});
// pass redis as context so our schema can use Redis methods
const wrapper = require('./filamentMiddleware')
app.use('/filament',
wrapper(client), // filamentMiddleware with access to client
)
app.use(
'/graphql',
graphqlHTTP((req) => ({
schema,
graphiql: true,
context: {
client,
req: req
}
})),
// addToCacheWrapper(res.data)
);
app.listen(PORT, () =>
console.log(`GraphQL server is running on port: ${PORT}`)
);
Middleware
const axios = require('axios')
const serverFilamentQuery = require('./serverFilamentQuery')
const mergeDataFromCacheAndServer = require('./mergeDataFromCacheAndServer')
const wrapper = (client) => (req, res, next) => {
const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
client.get(ip, (err, cacheData) => {
const { query } = req.body
// ip not found in cache
if (!cacheData) {
console.log('cacheData:', cacheData)
axios.post('/graphql', { query }).then(res => {
console.log('have we made the post ????')
// set redis cache
// set the new data in Redis
client.set(ip, JSON.stringify({
todos: res.data.data['todos']
}), (err, result) => {
console.log(result)
})
const { data } = res.data
// return combinedData to client
return res.status(200).json({ data })
})
}
// console.log('ip found in cache')
const [newQuery, data, isMatched] = serverFilamentQuery(query, cacheData)
if (isMatched) {
return res.status(200).json({ data })
} else {
axios.post('/graphql', { newquery }).then(res => {
const merged = mergeDataFromCacheAndServer(data['todos'], res.data.data['todos']);
// set the new data in Redis
console.log(merged)
client.set(ip, JSON.stringify({
todos: merged
}), (err, result) => {
console.log(result)
})
// return combinedData to client
return res.status(200).json({ merged })
})
}
})
}
module.exports = wrapper
Yes, there is no problem making a post request server-side with Axios.
As per the Axios GitHub page
Promise based HTTP client for the browser and node.js (ie. server-side)
Note that the server-side call/usage is slightly different though, as per the docs here
versus client-side call here

POST request body is undefined using koa-body

Its my first time trying to do a POST request with Postman using Koa in my application. I have the router and the body parser but for some reason i still get an error message sayng that my request body is undefined. I think the body parser is not working but i have no idea why.
routes.js
const Koa = require('koa');
const bodyParser = require('koa-body')
const Router = require('koa-router')
const app = new Koa()
const router = new Router()
const Topic = require('./models/topic')
router.post('/topics', bodyParser(), async (ctx) => {
console.log(JSON.stringify(ctx.request.body))
const { name } = ctx.request.body
newPost = {
name: {name}
}
let newTopic = new Topic(newPost)
await newTopic.save(function(error, newPost){
if (error) {
console.log(error)
} else {
res.status(201).json({
message : 'Name added!'
}).send(newPost)
}
})
return
})
app
.use(router.allowedMethods())
.use(router.routes())
module.exports = router
topic.js
const mongoose = require('mongoose')
const Schema = mongoose.Schema
const TopicSchema = new Schema(
{
name: {type: String, required: true },
viewCount: {type: Number, default: 0 }
},
{
timestamps: true
}
)
module.exports = mongoose.model('two/Topic', TopicSchema)
Error message:
{}
Error: two/Topic validation failed: name: Cast to string failed for value "{ name: undefined }" at path "name"
at ValidationError.inspect (/home/node/app/node_modules/mongoose/lib/error/validation.js:47:26) ...
EDIT
Also adding in server.js for further reference
const Koa = require('koa');
const mongoose = require('mongoose');
const router = require('./routes');
const app = new Koa();
app.use(require('koa-body')());
app.use(router.routes());
mongoose.connect(process.env.MONGODB_URI, { useNewUrlParser: true, useUnifiedTopology: true })
.then(() => {
const listener = app.listen(process.env.APP_PORT || 3000, () =>
console.log('App started on port ' + listener.address().port)
)
})
.catch((error) => {
console.log(error)
process.exit(1)
})
// app.proxy = true;
module.exports = app;

Agenad job is not getting start again after nodejs (express) server restart

I am using node agenda while scheduling I am able to successfully save job and its running fine. But while restarting the server the previous jobs are not getting start again. Not sure why, I tried few solutions found online but unable to make it work.
Can anyone help me with this.
I am using Nodemon with node express.
I am creating schedule using API calls
Below is app.js file
'use strict';
require('dotenv').config();
const express = require('express');
const { initialize_mongodb_database_connection } = require('./helpers/mongodb_database');
const bodyParser = require('body-parser');
const Agenda = require('agenda');
const app = express();
let logger = require('logger');
let chalk = require('chalk');
let moment = require('moment');
let mongoose = require('mongoose');
const agenda = new Agenda({
db: {address: process.env.MONGODB_URI, collection: 'scheduled_reports'},
processEvery: '30 seconds'
});
app.use(bodyParser.json());
//
// Parse application/x-www-form-urlencoded
//
app.use(bodyParser.urlencoded({extended: false}));
app.use(require('./routes/v1/schedule_report/schedule_report_routes'));
initialize_mongodb_database_connection();
sequr_app(app, [dummy_routes], {
staticDir: true,
});
let gracefulExit = function() {
if (mongoose.connection.readyState === 0) {
return process.exit(0);
}
mongoose.connection.close(function() {
return agenda.stop(function() {
logger.info({});
logger.info(chalk.bold("---------------------[ Server stopped at %s Uptime: %s ]---------------------------"), moment().format("YYYY-MM-DD HH:mm:ss.SSS"), moment.duration(process.uptime() * 1000).humanize());
return process.exit(0);
});
});
};
process.on("SIGINT", gracefulExit).on("SIGTERM", gracefulExit);
And this is my agenda file where I am routing API calls to create schedule
const Agenda = require('agenda');
var nodemailer = require('nodemailer');
var transporter = nodemailer.createTransport({
service: 'gmail',
host: 'smtp.gmail.com',
auth: {
user: 'xx-xx#gmail.com',
pass: 'xx-xx-xx'
}
});
var mailOptions = {
from: 'example#example.com',
to: 'Example#gmail.com',
subject: 'Sending Email using Node.js',
text: 'Agenda Test'
};
const agenda = new Agenda({
db: {address: process.env.MONGODB_URI, collection: 'agendaJobs'},
processEvery: '30 seconds'
});
agenda.start();
agenda.defaultConcurrency(5);
const scheduleReport = async(report_data) => {
// HERE SCHEDULING/CREATING AGENDA SCHEDULE
agenda.on('start', job => {
console.log('-------------------------------------STARTED-----------------------------------------------');
console.log('Job %s starting', job.attrs.name);
console.log('-------------------------------------------------------------------------------------------');
});
const {
report_name,
priority
} = report_data;
agenda.define(report_name, {priority: priority, concurrency: 10}, (job, done) => {
const dateNow = new Date();
const data = job.attrs.data;
// The job.attrs.data is stored in our MongoDB collection so that it can be used to run the jobs.
transporter.sendMail(mailOptions, function(error, info){
if (error) {
console.log(error);
} else {
//const date = new Date.now();
console.log('Email sent: ' + info.response + dateNow);
console.log(`Job ${job.attrs.name} finished`);
}
},done());
});
// HERE CREATING SCHEUDLE
await createWeeklySchedule(report_data);
agenda.on('complete', job => {
console.log('---------------------------------------FINISHED---------------------------------------------');
console.log(`Job ${job.attrs.name} completed succesfully...`);
console.log('--------------------------------------------------------------------------------------------');
});
}
const createWeeklySchedule = async(data) => {
const {
report_name,
schedule_info,
scheduled_timezone,
time_cron
} = data;
const weeklyReport = agenda.create(report_name, {data: schedule_info});
await agenda.start();
await agenda.every(time_cron,report_name);
console.log('Job successfully saved');
}
module.exports = scheduleReport;
Also I am starting app with app.js as main

How to filter MongoDB collection document's array

I am new in MongoDB and need a help. In my DB I am trying to create a collection, which has only one document.T hat document has a simple key ` cities, which is an array of 124247 objects. Here is my code
const express = require('express');
const bodyParser = require('body-parser');
const mongoose = require("mongoose");
const cities = require('cities.json');
const Schema = mongoose.Schema;
const db = mongoose.connection;
const app = express();
mongoose.connect("mongodb://localhost:27017/cities");
db.once("open", function() {
console.log("Connection ok.");
})
const cityScheme = new Schema({
cities: Array
});
const WorldCities = mongoose.model("WorldCities", cityScheme);
const myCities = new WorldCities({
cities: cities
}).save().then(data => console.log({}.toString.call(data.cities), 'dataaa'));
WorldCities.find({
name: "Yerevan"
}, function(err, data) {
console.log(data, 'Armenia');
});
cityScheme.statics.getSearchedcity = function(res) {
this.find({}, (err, citysList) => res.json({
citysList
}));
}
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
app.get('/api/city', (req, res) => {
})
app.listen(3000);
This is the link to cities.json ` Cities.json .
So here I want to find the city with name Yerevan, but I don't know how to find it.
You are using mongoose and from the look of your raw data it seems you are looking for only one document ... also it seems your schema is defined so that you have the cities property which contains the cities objects from your JSON so:
WorldCities.findOne({
'cities.name': "Yerevan"
}, function(err, model) {
// do something with the model here
console.log(model);
});
findOne will locate only one document for you and return it in the callback.
See if this will get you the record.
Use .filter
Ex:
arrayOfCiteis.filter(myC => myC.name === "Yerevan")

Categories