I am doing a practise project in Node/Express.
My server.js looks like this:
const express = require("express")
const app = express()
const bodyParser = require("body-parser")
const morgan = require("morgan")
const { get } = require("http")
const PORT = 3000
const budgetRoute = require("./routes/Budget")
const envelopeRoute = require("./routes/Envelopes")
const envelopeNameRoute =require("./routes/Envelopes_name")
const envelopeTransferRoute =require("./routes/Envelopes_transfer")
global.envelopes = []
global.totalBudget = 0
app.use(bodyParser.json())
app.use(morgan("dev"))
app.use("/envelopes", envelopeRoute)
app.use("/envelopes/:name", envelopeNameRoute)
app.use("/envelopes/transfer/:name", envelopeTransferRoute)
app.use("/budget", budgetRoute)
app.listen(PORT, () =>{
console.log(`Listening on port ${PORT}`)
})
now in my Route file routes/Envelopes_name I have this:
router.put("/", (req,res,next)=>{
const envelopeToChangeName = req.params.name
const envelopeName = req.query.name
const envelopeBudget = req.query.budget
const reqEnvelope = envelopes.find(envelope => envelopeToChangeName)
if(envelopeBudget){
reqEnvelope.budget = envelopeBudget
}
if(envelopeName){
reqEnvelope.name = envelopeName
}
res.status(201).send(reqEnvelope)
})
after sending request localhost:3000/envelopes/groceries?name=taxes it should change the name of the envelope from "groceries" to "taxes". For some reason req.params.name is "undefined" and I have error "TypeError: Cannot set properties of undefined (setting 'name')". When I had it all in one file, without routers, it worked perfectly. Any ideas?
I think you need to add { mergeParams: true } to make the params available, because you use another router file then where you define the route.
See Express docs
Related
I am trying to display data from sample collection thats in mongoDB Atlas. i have connected to the server, retrieved the data. But the problem is i cannot choose specific data. if i do it says undefined.
Here is the pic and code for better understanding:
MY MOVIE MODEL movie.js
const mongoose = require("mongoose");
const { Schema } = mongoose;
require("dotenv").config();
const mongoDB_API = process.env.MONGODB_API_KEY;
const mflixDB = mongoose.createConnection(mongoDB_API).useDb("sample_mflix");
const Movies = mflixDB.model("Movie", new Schema({}), "movies");
module.exports = Movies;
I used the code via mongoose access preexisting collection
Snippet of MongoDB ATLAS:
my app.js
const express = require('express');
const bodyParser = require('body-parser');
const _ =require('lodash');
const mongoose = require('mongoose');
require('dotenv').config();
const app = express();
app.set("view engine","ejs");
app.use(bodyParser.urlencoded({extended:true}));
app.use(express.static('public'));
const Movies = require('./model/mflix/movies');
app.get("/movies",async (req, res) => {
const ourMovies = await Movies.find().sort({'date': -1}).limit(2);
console.log("WE recieved: \n")
console.log(ourMovies);
const titles =[];
ourMovies.forEach( x=>{
console.log(x._id, x.title)
})
res.render("movies", { recievedList: ourMovies });
});
the output:
As u can see x.title is undefined instead of respective title.
I cannot access any info other than _id.
Is this because i didn't properly defined my schema for the model ?
How do i fix this?
I was browsing more on this answer(this link) and decided to try other ways to do similar thing
Solution from this: Solution, i tried that soliton and added it in my code in following manner:
in app.js
const express = require('express');
const bodyParser = require('body-parser');
const _ =require('lodash');
const mongoose = require('mongoose');
require('dotenv').config();
const app = express();
app.set("view engine","ejs");
app.use(bodyParser.urlencoded({extended:true}));
app.use(express.static('public'));
//we dont really need this (UNUSED)
const Movies = require('./model/mflix/movies');
const mongoDB_API = process.env.MONGODB_API_KEY;
const mflixDB = mongoose.createConnection(mongoDB_API).useDb("sample_mflix");
app.get("/movies", async (req, res) => {
const collection = mflixDB.collection("movies");
collection
.find({})
.limit(2)
.toArray(function (err, data) {
console.log("\nour data:");
console.log(data); // it will print your collection data
data.forEach(x=>{
console.log(`Id: ${x._id} \t title: ${x.title}`)
})
});
const ourMovies = await Movies.find().sort({ date: -1 }).limit(2);
// console.log("WE recieved: \n")
// console.log(ourMovies);
// const titles =[];
// ourMovies.forEach( x=>{
// console.log(x._id, x.title)
// })
res.render("movies", { recievedList: ourMovies });
});
The output:It shows title (and not undefined like above question)
I am trying the following code from TutorialPoint's website for my GraphQL implementation. from the Tutorial Points example : GraphQL link.
const bodyParser = require('body-parser')
const cors = require('cors')
const express = require('express')
const port = process.env.PORT||9000
const app = express()
app.use(bodyParser.json() , cors())
const typeDefinition = `
type Query {
greeting: String
}`
const resolverObject = {
Query : {
greeting: () => 'Hello GraphQL From TutorialsPoint !!'
}
}
const {makeExecutableSchema} = require('graphql-tools')
const schema = makeExecutableSchema({typeDefs:typeDefinition, resolvers:resolverObject})
const {graphqlExpress,graphiqlExpress} = require('apollo-server-express')
app.use('/graphql',graphqlExpress({schema}))
app.use('/graphiql',graphiqlExpress({endpointURL:'/graphql'}))
app.listen(port, () => console.log(`server is up and running ${port}`))
But the issue is that when I run the above code as mentioned in the tutorial. I am running into the following error.
I have installed all the mentioned dependencies and ran the code through
http://localhost:9000/graphiql
I am not able to figure out what the issue is.
In this fictive project I am trying to set up the Routing structure. Although I used module.exports in both files, running a test still gives me the following error:
TypeError: Router.use() requires a middleware function but got a Object
My Code:
Minions.js
const minionsRouter = require('express').Router();
module.exports = minionsRouter;
const {
getAllFromDatabase,
addToDatabase,
getFromDatabaseById,
updateInstanceInDatabase,
deleteFromDatabasebyId,
} = require('./db.js');
minionsRouter.get('/', (req, res, next) => {
const minionsArray = getAllFromDatabase('minions');
if (minionsArray) {
res.status(200).send(minionsArray);
} else {
res.status(404).send();
}
});
API.js
const express = require('express');
const apiRouter = express.Router();
const minionsRouter = require('./minions');
const ideasRouter = require('./ideas');
const meetingsRouter = require('./meetings');
apiRouter.use('/minions', minionsRouter);
apiRouter.use('/ideas', ideasRouter);
apiRouter.use('/meetings', meetingsRouter);
module.exports = apiRouter;
Server.js
const express = require('express');
const app = express();
module.exports = app;
/* Do not change the following line! It is required for testing and allowing
* the frontend application to interact as planned with the api server
*/
const PORT = process.env.PORT || 4001;
// Add middleware for handling CORS requests from index.html
const cors = require('cors');
app.use(cors());
// Add middleware for parsing request bodies here:
const bodyParser = require('body-parser');
app.use(bodyParser.json());
// Mount your existing apiRouter below at the '/api' path.
const apiRouter = require('./server/api');
app.use('/api', apiRouter);
// This conditional is here for testing purposes:
if (!module.parent) {
// Add your code to start the server listening at PORT below:
app.listen(PORT, () => {
console.log(`Server is listening on port ${PORT}`)
})
};
Any help is much appreciated!
This is my index.js file and i think i have placed the routes after installing bodyParser but still getting the syntax error.
const express = require('express'); //Framework to build server side application
const morgan = require('morgan'); //Logging the nodejs requests
const bodyParser = require('body-parser'); //To get the JSON data
const urls = require('./db/urls');
const app = express();
app.use(morgan('tiny'));
app.use(bodyParser.json());
app.use(express.static('./public')); //If a request comes with '/' check if file is in there if it is then serve it up.
// app.get('/', (req, res) => {
// res.send('Hello, World !!');
// });
app.post('/api/shorty', async (req, res) => {
console.log(req.body);
try {
const url = await urls.create(req.body); //Passing the body data which is JSON to create function
res.json(url);
} catch (error) {
res.status(500);
res.json(error)
}
});
const port = process.env.PORT || 5000;
app.listen(port, () => {
console.log(`listening on port ${port}`);
});
This is the urls.js file,I am not getting where have i messed up to make Syntax.JSON error in this file.
const db = require('./connection');
const Joi = require('joi');//Schema validation
const urls = db.get('urls');
const schema = Joi.object().keys({
name : Joi.string().token().min(1).max(100).required(),
url : Joi.string().uri({
scheme: [
/https?/ //get http 's' is optional
]
}).required()
}).with('name','url');
//almostShorty = {
// name = ,
// url =
// }
function create(almostShorty){
const result = Joi.validate(almostShorty, schema);
if(result.error === null){
return urls.insert(almostShorty);//Inserting the object in the Data Base.
}else{
return Promise.reject(result.error);
}
};
module.exports = {create};//Exporting the create function.
I am just starting in nodejs.
I am instantiating a logger (Pino) in server.js which is the entry point. I only want to create one instance of that logger and use it in other modules.
'use strict';
const express = require('express');
const pino = require('pino');
const log = pino({ level: process.env.LOG_LEVEL || 'info' });
const ping = require('./routes/ping'); //new
const app = express();
app.use('/api/ping', ping);
const port = 3000;
app.listen(port, () => {
console.log(`API server started on ${port}... ^C to end`);
});
module.exports = { app, log }; //edited
So in ping.js how do I get access to log in services.js?
const express = require('express');
const router = express.Router();
const { log } = require('../server'); //edited
router.get('/', async function(req, res) {
log.info('someone pinged');
res.sendStatus(200);
});
module.exports = router;
Edited with suggestions.
You can attach the logger as a property on your app object or on app.locals. Then a reference to it will be accessible through req.app.logger or req.app.locals.logger or whatever in your middlewares and route handlers.
'use strict';
const path = require('path');
const express = require('express');
const ping = require('./routes/ping');
const pino = require('pino');
const log = pino({ level: process.env.LOG_LEVEL || 'info' });
var app = module.exports = express();
app
.use('/api/ping', ping);
const port = config.SERVER_PORT || 3000;
app.listen(port, () => {
console.log(`API server started on ${port}... ^C to end`);
});
module.exports = {app,pino}
Now you can import the same pino instance anywhere.
const log = require('./server.js').pino