Node, Mongoose, Redux: GET request failure - node.js

I am trying to make the following get request, which is intended to simply return documents from a collection. Once I get the data, it should flow through a reducer into the redux state object. But the get request fails.
var QuestionModel = require('./src/models/fv-questionModel')
mongoose.connect('mongodb://localhost/FVDB')
var app = express();
app.use(compression())
app.use(express.static(path.join(__dirname, 'public')));
app.set('port', process.env.PORT || 8080);
app.get('/api/recent', (request, response) => {
if (error) {
console.log(error)
}
// Get documents and perform callback on recentQuestions data
QuestionModel.find((error, recentQuestions) => {
if (error) {
response.send('unable to retrieve data')
} else {
response.json(recentQuestions)
}
})
})
this request was working until I changed the structure of the data in the collection. Here is my current mongoose schema:
const questionSchema = new mongoose.Schema({
title: String,
options: [{ oid: Number, choice: { name: String, count: Number } }],
qid: Number,
})
const QuestionModel = mongoose.model('Question', questionSchema, 'questionBank')
module.exports = QuestionModel
The previous schema:
const questionSchema = new mongoose.Schema({
title: String,
options: Array,
qid: Number,
})
Here is the Redux action that makes the GET request:
export function recentQuestions() {
let recentQs = axios.get('/api/recent')
return {
type: 'GET_RECENT',
payload: recentQs,
}
}
And the reducer to handle that data:
export default function(state = null, action) {
switch (action.type) {
case 'GET_RECENT':
return action.payload.data
}
return state
}
But when the GET request is made, it returns a '404: Not Found' error. When I navigate my browser to localhost:8080/api/recent I get the message 'cannot GET /api/recent'. The express server itself is working.
I cannot for the life of me figure out why this request is no longer working. I know there are other questions about failed GET requests but none seem to pertain to this issue. Any help would be greatly appreciated.

Related

how to get the existing collection in mongodb using mongose- Nodejs

In my mongodb i already had a collection and document
Now, i want to use this collection in my node-js using mongoose. how we do this.
const mongoose = require("mongoose");
const schema = mongoose.Schema;
const adminLogin = new schema({
name: { type: String, required: true },
password: { type: String, required: true }
})
module.exports = mongoose.model("adminDetails", adminLogin)
while doing this it is creating new collection. Unable to use the existing collection.
At first you need to make a GET method Router in your jsFile.
like this
app.get("/mainData", async (req, res) => {
const menuInfo = await Nutrients.find({});
res.json(menuInfo);
});
You can set and use VSCode extension "thunderClient"!
like this
enter image description here
setting your request method and URI endpoint
(when you user GET method to get some data in your case, you don't need to write something in request body)
Then, you can see your data on the 'response part' as an Object Data.
If you want to use your data on Front side on your Project, you can use like this!
(in my case, I used jQuery. )
function menu_show() {
$('#result_list').empty()
$.ajax({
type: 'GET',
url: '/mainData', //you need to write same url with your no3.
data: {},
success: function (response) {
console.log(response)
let rows = response['menus']
for (let i = 0; i < rows.length; i++) {
let menuName = rows[i]['menuName']
console.log(menuName)
}
}
}
This is my answer. Let me know if you've solved it!
the image 1 is the structure in the MongoDB. I want to read the data from that collection, below is the code using and the URL and output in post man.
route.get('/adminLogin', (request, response) => {
const data = adminDetails.find({}, (err, result) => {
if (err) {
console.log(err)
} else {
res.json(result)
}
})
})
http://localhost:5000/admin/adminLogin

Req.body returns undefined : ExpressJs, NodeJs

Please help me I'm having this error for 5 days.
I'm trying to delete data inside of my array on MongoDB
but my req.body returns undefined even though I have my body-parser. I'm using axios.patch for request.
It works well in my postman but once I sent data that's where the problem occurs.
Here's my axios api call.
export const deleteTask = (id,post) => api.patch(`/main/${id}`, post);
Here's my schema.
const todoSchema = mongoose.Schema({
username: {
type: String,
},
password: {
type: String,
},
task: [String],
time: {
type: Date,
default: Date.now,
}
});
const TodoModels = mongoose.model('TodoModels', todoSchema);
here's my query.
export const deleteTask = async (req,res) => {
const { id } = req.params;
console.log(req.body);
if(!mongoose.Types.ObjectId.isValid(id))
return res.status(404).json(`Invalid ID`);
await TodoModels.findByIdAndUpdate(id,{$pull:{ task: req.body.task }},{
new: true });
}
My req.body has no task and I don't know why. Once I send data it returns undefined but the ID from req.params is not undefined.
Also once I sent the data from client to backend/server req.body returns this { data: '' } the data I sent became the element. I believe it was supposed to be { task: 'data' }
If your deleting a record then why are you using findByIdAndUpdate ; it should be findByIdAndDelete. I have put a sample code you to refer. There are 2ways you can delete a record. You can try them out and see.
Way 1:
router.delete('/:id', [auth, admin, validateObjectId], async(req, res) => {
//check for existing genre
const movieGenre = await Genre.findByIdAndDelete(req.params.id);
if (!movieGenre) {
return res.status(404).send('No such movie genre found with given id.');
}
res.send(movieGenre);
})
Way 2:
router.delete('/:id', [auth, admin, validateObjectId], async(req, res) => {
//second way to delete
let movieGenre = await Genre.findById(req.params.id);
if (!movieGenre) {
return res.status(404).send('No such movie genre found with given id.');
}
await movieGenre.deleteOne();
const index = genres.indexOf(movieGenre);
genres.splice(index, 1);
res.send(movieGenre);
})
Hope the answer helps you in any way.

Graphql query is always returning null

I am trying to get course data using graphql, but server is always returning null as a response This is my code in file server.js :
var express=require('express');
const { graphqlHTTP } = require('express-graphql')
var {buildSchema}=require('graphql');
//graphql schema
var schema=buildSchema(`
type Query {
course(id: Int!): Course
courses(topic:String!):[Course]
}
type Course {
id: Int
title: String
author: String
description:String
topic:String
url: String
}
`);
var coursesData = [
{
id: 1,
title: 'The Complete Node.js Developer Course',
author: 'Andrew Mead, Rob Percival',
description: 'Learn Node.js by building real-world applications with Node, Express, MongoDB, Mocha, and more!',
topic: 'Node.js',
url: 'https://codingthesmartway.com/courses/nodejs/'
},
{
id: 2,
title: 'Node.js, Express & MongoDB Dev to Deployment',
author: 'Brad Traversy',
description: 'Learn by example building & deploying real-world Node.js applications from absolute scratch',
topic: 'Node.js',
url: 'https://codingthesmartway.com/courses/nodejs-express-mongodb/'
},
{
id: 3,
title: 'JavaScript: Understanding The Weird Parts',
author: 'Anthony Alicea',
description: 'An advanced JavaScript course for everyone! Scope, closures, prototypes, this, build your own framework, and more.',
topic: 'JavaScript',
url: 'https://codingthesmartway.com/courses/understand-javascript/'
}
]
//root resolver
var root= {
course:getCourse,
courses:getCourses
};
var getCourse= function (args){
var id=args.id;
console.log("delila")
return coursesData.filter(course=>{
return course.id==id
})[0]
}
var getCourses = function(args){
if(args.topic){
var topic=args.topic;
return coursesData.filter(course=>
course.topic===topic
);
}
else return coursesData
}
//create an experess server and graphql endpoint
var app=express();
app.use('/graphql', graphqlHTTP({
schema: schema,
rootValue:root,
graphiql:true
}));
app.listen(4000,()=>console.log("delila express graphql server running on localhost 4000"))
When I go to localhost:4000/graphql to get data I am using
query getSingleCourse($courseID: Int !){
course(id:$courseID){
title
author
description
url
topic
}
}
{
"courseID": 3
}
But I am constantly getting result null. Look at image
Anyone idea why is happening this? Server should return course with id 3 but obviously there is something that I am missing
You should define function expression first and then use them. That's the reason.
Function expressions in JavaScript are not hoisted, unlike function declarations. You can't use function expressions before you create them:
See Function expression
E.g.
//...
var getCourse = function (args) {
var id = args.id;
console.log('delila');
return coursesData.filter((course) => {
return course.id == id;
})[0];
};
var getCourses = function (args) {
if (args.topic) {
var topic = args.topic;
return coursesData.filter((course) => course.topic === topic);
} else return coursesData;
};
//root resolver
var root = {
course: getCourse,
courses: getCourses,
};
//...

TypeError: expected string but received array postman

I was trying to send form data that has multiple fields with the same name, I'm getting back "TypeError: expected string but received array".
I think the problem is with postman, I want to have multiple participant fields, and those would be added to the should be added to the array.
final results of array
// this is from models/Battle
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// Create Schema
const BattleSchema = new Schema({
user: {
type: Schema.Types.ObjectId,
ref: 'users'
},
date: {
type: Date,
default: Date.now
},
category: {
type: Number,
required: true // this will come from the selected category
},
winner: {
type: Number,
default: 0
},
status: {
type: Number,
default: 0 // 0 means the battle is closed, 1 means the battle is open for votes, the status will stay 0 until all participants dropped
},
participants: [
{
participant: {
type: Schema.Types.ObjectId,
required: true
}
}
]
});
module.exports = Battle = mongoose.model('battles', BattleSchema);
//this is from routes/api/battles
// #route POST api/battles
// #desc Create battle
// #access Private
router.post(
'/create-battle',
passport.authenticate('jwt', { session: false }),
(req, res) => {
const { errors, isValid } = validateBattleInput(req.body);
// Check Validation
if (!isValid) {
// If any errors, send 400 with errors object
return res.status(400).json(errors);
console.log(errors);
}
const newBattle = new Battle({
user: req.user.id,
category: req.body.category,
participant: req.body.participant
});
//save
newBattle.save().then(battle => {
// const participant = req.body.participant;
const participant = req.body.participant;
// add participants to array
battle.participants.push( participant );
console.log(typeof req.body.participant);
// get the inserted id
const battleId = battle._id;
res.json(battle);
});
}
);
// this is battle validation
const Validator = require('validator');
const isEmpty = require('./is-empty');
var bodyParser = require('body-parser');
module.exports = function validateBattleInput(data) {
let errors = {};
data.category = !isEmpty(data.category) ? data.category : '';
data.participant = !isEmpty(data.participant) ? data.participant : '';
if (Validator.isEmpty(data.category)) {
errors.category = 'Category field is required';
}
// if (Validator.isEmpty(data.challenger)) {
// errors.challenger = 'Challenger field is required';
// }
if (Validator.isEmpty(data.participant)) {
errors.participant = 'Participant field is required';
}
return {
errors,
isValid: isEmpty(errors)
};
};
TypeError: Expected string but received Array. ---throws an error in postman as well as in a terminal window. I suspect it could be the user schema definition mismatch
Please check your user model user schema eg
name: {
type: String,
required: true
}
it's receiving something else than expected.
try in your "body" tab, selecting "raw", and then to the right, select "JSON (application/json)" instead of "text".
I'm assuming your API endpoint uses JSON instead of a url-encoded form data, just because you are running an API using express and mongoose. but you should clarify that on the question if it isn't the case.
Write a proper JSON body, I mean, use double quotes for keys as in:
{"model": { "property": "value", "property2": 1}}
and try with the wrapping object {"model": <YOUR BODY HERE>} or without to see what works for you, as it's typical to wrap the object, but sometimes people don't use them. (seeing this in your code: req.body.participant makes me think you probably don't).
(PS: not related with the question, but personally prefer ARC or Insomnia for rest clients, as the interface for them is cleaner)
If you want data to be sent in participants array all the fields should be participants and not participant
try sending data through raw data and then selecting application/data for better formatting
When testing in postman - Just figured out Key value must match your validation function defined variables. It's better to be consistent across your development.

Completely stuck. (MongoDB / MERN issue)

Im creating an app, and right now I'm working on a feature that takes in user input, and stores it in the database. I've done this plenty of times on other projects, but have come to a problem that I just can't solve.
So far, when a user types in their info and hit's enter, the data is sent to the back end, and start's to head towards the endpoint. I have a controller set up with my 'create' function. It is the following:
const db = require('../database/models');
module.exports = {
// create: function(req, res) {
// console.log('hit controller');
// db.Listing
// .create(req.body)
// .then(dbModel => res.json(dbModel))
// .catch(err => res.status(422).json(err));
// }
create: function(req, res) {
console.log('!!!!HERE:CONTROLLERS' + req.body.receiver);
db.Listing
.create(req.body)
.then(function(dbModel) {
console.log(dbMessage);
res.json(dbModel)
})
.catch(function(err) {
res.json(err);
});
}
};
I have two functions because I tried something a little different for each with the same result. Once it gets to this point, I get the following error ('hit controller' is just the console.log in the create function):
'hit controller'
TypeError: Cannot read property 'create' of undefined
I also get the following error in my console on the browser: xhr.js:178 POST http://localhost:3000/listing/ 500 (Internal Server Error) err from saveListing Error: Request failed with status code 500 at createError (createError.js:16) at settle (settle.js:18) at XMLHttpRequest.handleLoad (xhr.js:77)
Which is coming from my addListing page:
handleFormSubmit = (event) => {
event.preventDefault();
console.log('hit');
console.log("state in handle submit", this.state.title)
if (
this.state.title &&
this.state.description &&
this.state.duration &&
this.state.datesAvailable &&
this.state.tags
) {
API.saveListing({
title: this.state.title,
description: this.state.description,
duration: this.state.duration,
datesAvailable: this.state.datesAvailable,
tags: this.state.tags
})
.then(res => console.log('success'))
.catch((err) => console.log("err from saveListing", err));
}
};
Here is my models file:
var mongoose = require("mongoose");
var Schema = mongoose.Schema;
var ListingSchema = new Schema({
// `title` is of type String
title: {
type: String,
required: true
},
description: {
type: String,
required: true
},
duration: {
type: String,
required: true
},
datesAvailable: {
type: String,
required: true
},
hashtags: {
type: Array,
required: true
}
});
var Listing = mongoose.model("Listing", ListingSchema);
module.exports = Listing;
So re-cap: When the user hit's the submit button, the form runs a function, hit's the API with the route it needs, heads to the sever, then to the route for the post request, then the llistingController for the create function for the post, while pulling from my Listing DB model. Once the create function is reached, it poops out. The data is apparently undefined, but I don't know why and can't figure it out.
I feel like what I'm running into is probably basic as fuck but I can't for the life of me figure it out. Additionally if anyone knows some bad ass resources for adding to my mongo/express/react knowledge i'd love to see it.
You're importing db from the models file, but that file is exporting Listing. Import Listing and use Listing.create instead of db.Listing.create.
As 223seneca said, I changed db.Listing.create in my controller to just Listing.create. Then I required Listing in the controller file to the exact file, instead of to just the models folder('const Listing = require('../database/models/Listing');' instead of 'const Listing = require('../database/models');'.
That was all I needed!

Resources