I have been doing a project in URL shortening and i am getting an undefined as a result to get request.
Also i get a blank page too as result,but according to my knowledge everything is ok,i can't figure out what is the mistake
Here's my code(please check the app.get section)
'use strict';
var bodyParser = require('body-parser')
var express = require('express');
var mongo = require('mongodb');
var mongoose = require('mongoose');
var http = require("http");
var cors = require('cors');
const dns = require('dns');
var app = express();
// Basic Configuration
var port = process.env.PORT || 3000;
/** this project needs a db !! **/
// mongoose.connect(process.env.DB_URI);
app.use(cors());
/** this project needs to parse POST bodies **/
// you should mount the body-parser here
app.use('/public', express.static(process.cwd() + '/public'));
app.get('/', function(req, res){
res.sendFile(process.cwd() + '/views/index.html');
});
// your first API endpoint...
app.get("/api/hello", function (req, res) {
res.json({greeting: 'hello API'});
});
mongoose.connect(process.env.MONGO_URI, { useNewUrlParser: true, useUnifiedTopology: true });
var saveSchema = new mongoose.Schema({
name: String,
url: Number,
});
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
/** 3) Create and Save a Person */
var SaveData = mongoose.model('Save', saveSchema);
//**Here's the start of my problem,i think**
app.get("/api/shorturl/:id1",function(req,res){
SaveData.find({url:1},function(err,data){ console.log(data.name)//**i am getting undefined for this in console**
res.json(data.name);})
});
app.post("/api/shorturl/new",(req,res)=>{
var body=req.body.url;
dns.lookup(body,(err,data)=>{
var new2= new SaveData({name:body,url:1});
new2.save((err,data)=>{res.json(new2);});
})
});
app.listen(port, function () {
console.log('Node.js listening ...');
});
I checked my DB whether the schema data is inputted or not, it is getting inside DB, so retrieval makes the problem I think.
mongoose.model.prototype.find returns an array of objects found. If you type Array.prototype.name in a console somewhere, you'll get undefined. Instead, use mongoose.model.prototype.findOne.
Your enviorment variables are working? I notice you're not using dotenv module or something like that to configure your process.env.
Related
In this example below, you can see that the csrfProtection and parseForm functions are passed as parameters/callbacks in the GET and POST requests...
var cookieParser = require('cookie-parser')
var csrf = require('csurf')
var bodyParser = require('body-parser')
var express = require('express')
// setup route middlewares
var csrfProtection = csrf({ cookie: true })
var parseForm = bodyParser.urlencoded({ extended: false })
// create express app
var app = express()
// parse cookies
// we need this because "cookie" is true in csrfProtection
app.use(cookieParser())
app.get('/form', csrfProtection, function(req, res) { // HERE
// pass the csrfToken to the view
res.render('send', { csrfToken: req.csrfToken() })
})
app.post('/process', parseForm, csrfProtection, function(req, res) { // AND HERE
res.send('data is being processed')
})
However, if you are using a router, like I am, how can use these same functions? I am aware that by "using" them in app.js, they are made available on the req object but in the example given above, they are required as the 2nd and 2nd & 3rd arguments of the GET and POST routes, but req isn't made available until you're inside the final callback?!
So I know you can't do the below (just as an example)... so how should you use them? Would I have to re-declare them in every routes file?
Separate routes file: routes/someroute.js
...
router
.post('/', req.body, req.csrfProtection, (req, res) => {
})
...
Thanks in advance :)
Reference: https://www.npmjs.com/package/csurf
UPDATE
Following comments below, I have made the following changes to my app.js file.
app.js
...
global.bodyParser = require('body-parser').urlencoded({extended: false});
app.use(global.bodyParser);
global.csrfProtection = csrf({ cookie: false });
...
routes/myroute.js
router
.post('/', global.bodyParser, global.csrfProtection, (req, res) => {})
However, when I restart the server I am seeing this error, which suggests that that the global function is not defined... what am I missing here? :-/
Error: Route.post() requires a callback function but got a [object Undefined]
I think you ask about sharing middlewares across all API/routes files
You can do it like this :
First in your main file lets call it server.js we use you're code
var cookieParser = require('cookie-parser')
var csrf = require('csurf')
var bodyParser = require('body-parser')
var express = require('express')
// create express app
var app = express()
// setup route middlewares
app.use(bodyParser.urlencoded({ extended: false }))
// parse cookies
app.use(cookieParser())
//enable your JS API/route script.
const awesomeAPI = require('./awesomeApi.js');
app.use('/awesome', awesomeAPI );
app.listen(3000);
Now you have file let's calle it awesomeApi.js
const express = require('express');
const awesomeApi = express.Router();
awesomeApi.route('/')
.post(req,res => {
//req.body present here. And body parser middle ware works.
})
module.exports = awesomeApi;
Hope this helps.
Some links:
https://expressjs.com/en/guide/using-middleware.html
https://expressjs.com/en/4x/api.html#express
I've got a simple Express server that uses the body-parser module to access POST-parameters. The app looks like this:
/index.js:
'use strict';
const express = require('express');
const app = express();
const apiRouter = require('./api/routes.js');
// Set our port for the server application
const port = process.env.PORT || 8080;
// Register the routes for the /api prefix
app.use('/api', apiRouter);
// Start server
app.listen(port);
console.log('The server is running on port ' + port);
/api/routes.js:
'use strict';
const express = require('express');
const router = express.Router();
const bodyParser = require('body-parser');
// Configure app to use bodyParser(). This will let us get the data from a POST
router.use(bodyParser.urlencoded({ extended: true }));
router.use(bodyParser.json());
// START ROUTES
router.post('/devices', (req, res) => {
console.log(req.body); // Returns {}
res.json(req.body);
});
module.exports = router;
The problem is that the req.body object is empty (Always returns an empty object {}). Since I already loaded the body-parser middleware I have no idea what else I can try. I hope you have any suggestions.
I used the app Postman for testing. It appeared that it sent the POST data as form-data instead of x-www-form-urlencoded. After changing this setting the data showed up.
So, as you may see I was the creator of the question "I am having this problem by passing over GET method". But now having kind of a problem with "Passing over with POST method" Here is my code to see what is going wrong. All I want to do is to print to say : "Hello (Whatever the user pass over name of).. If ExpressJS, doesn't work, can anyone show me in Javascript way?!
Here is the code.
var server = require('./server');
var router = require('./router');
var requestHandlers = require('./requestHandlers');
var handle = {
'/': requestHandlers.start,
'/start': requestHandlers.start,
'/upload': requestHandlers.upload,
'/show': requestHandlers.show
};
var express = require('express')
var app = express()
app.post('/view/users/:name', function(req, res) {
console.log(req.body.desc);
res.end();
});
app.listen(8080, function () {
console.log('listening on port 8000!')
})
The error I get when passing over is "Cannot GET /view/users/John"
you can access the path variable :name from req.params object
app.get('/view/users/:name', function(req, res) {
console.log(req.params.name);
res.end();
});
You need to add bodyParser before your routes:
var bodyParser = require('body-parser')
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
and then whatever you pass to the route, bodyParser will make it available within the request object.
I am building an api that will interface with the MongoDB database and have mounted it as a subapplication. I have defined a session variable in my server controller.
However, any time that the server files need to talk to the api files the session variables are never passed off.
Heres the app.js file
//app.js file
'use strict';
process.env.NODE_ENV = 'development';
var express = require('express');
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var session = require('express-session');
var MongoStore = require('connect-mongo')(session);
var flash = require('connect-flash');
var helmet = require('helmet');
var app = express();
app.use(helmet());
var port = process.env.PORT || 3000;
mongoose.connect("mongodb://localhost:27017/striv4");
var db = mongoose.connection;
// mongo error
db.on('error', console.error.bind(console, 'connection error:'));
app.use(session({
secret: 'secret',
resave: true,
saveUninitialized: false,
store: new MongoStore({
mongooseConnection: db
})
}));
app.use(flash());
// make user ID available in templates
app.use(function (req, res, next) {
res.locals.currentUser = {
username:req.session.username,
id: req.session.userId
};
next();
});
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser('secreter'));
app.use(logger('dev'));
var api = require('./app_api/routes/index');
var serverRoutes = require('./server/routes/index');
//static file middleware
app.use(express.static(__dirname + '/public'));
app.set('views',__dirname +'/server/views');
app.set('view engine','pug');
app.use('/',serverRoutes);
app.use('/api',api);
//custom error handler
app.use(function(error, req, res, next) {
res.status(error.status || 500);
res.send('Error: '+error.message);
});
app.listen(port);
console.log('Listening on port: '+port);
You've got the whole program listed so there is more than one way for this to have gone wrong. Here are my suggestions to fix this:
Check the version of express-session you've installed. (Just run npm ls in the terminal and in your root Node app folder where you're package.json file is). If it's equal to or greater than v1.5.0, you don't need the cookie-parser for sessions anymore. Comment out the app.use line for the cookie parser and see if this works.
If you still need cookie parser for some other reason, you should use the same secret for sessions and the cookie parser. In your code, you've set two different values for secret.
I've seen that the other big failure for sessions occurs if the session store is not correctly connected to your Node app. Cross-check that the database is available and working. In my experience, Express sessions will fail silently if it can't get to the DB.
Hope this helps.
I have this very simple code that stores superhero name and power to database.
All connections work normally. When i ran mongod i used --dbpath C:/nodeprojects/sankarit/data. I have tried change the path like 50 times with different paths.
So my code sends nimi and supervoima (name, superpower) from client side and it tries to add them to database but literally nothing happens in db. When i write console.log("yay it works") on save function, it says that its working. And if i console log superhero it seems to work normally.
Here is client side:
$http.post("api/juttu", {nimi: "besthero", supervoima: "whiskey"}).success(function(response){
console.log(response.data);
}).error(function(){
console.log("Error")
})
Here is my server.js:
var express = require('express');
var path = require('path');
var app = express();
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
mongoose.set('debug', true);
// SANKARI SCHEMA
var Sankari = require('./app/models/sankarit');
// CONTROLLERIT
var testCtrl = require('./server/testCtrl');
app.use(bodyParser.urlencoded({ extended: true}));
app.use(bodyParser.json());
app.use('/public', express.static(__dirname + '/public'));
// DB conn
// I have tried with /test, /heros, /sankariKanta, /sankarit
mongoose.connect('mongodb://127.0.0.1:27017/test');
mongoose.connection.once('connected', function() {
console.log("Connected to database")
});
//PORTTI
var port = process.env.PORT || 8080;
// ROUTER
var router = express.Router();
app.get('/', function(req, res) {
res.sendFile('index.html', {root: __dirname});
});
app.post("/api/juttu", testCtrl.juttu);
app.listen(port);
Here is the testCtrl:
var Sankari = require("../app/models/sankarit");
module.exports.juttu = function (req, res){
// Tried also var uusiSankari = new Sankari(req.body);
var uusiSankari = new Sankari();
uusiSankari.nimi = req.body.nimi;
uusiSankari.supervoima = req.body.supervoima;
uusiSankari.save(function(err){
if(err){
console.log(err);
} else{
// This is always showing up
console.log("This is working!");
}
});
};
Also when i try console.log(req.body); It is working correctly.
Here is schema(sankarit.js):
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var SankariSchema = ({
nimi: String,
supervoima: String
});
module.exports = mongoose.model('Sankari', SankariSchema);
When i run the program, the mongoose debug thing says:
Mongoose: sankaris.insert({ __v: 0, _id: ObjectId("57ff0a649dbf169c15000001"), nimi: 'besthero', s
upervoima: 'whiskey' }) {}
So when i debug and console log everything the program does it seems to work like dream. I have made these MEAN stack tutorials like 5-10 and everytime database worked normally. This is first time i'm trying to make whole code by myself. I tried solve this whole night but i didn't get absolutely anywhere.
You forgot to use the Schema
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var SankariSchema = Schema({
nimi: String,
supervoima: String
});
module.exports = mongoose.model('Sankari', SankariSchema);