I have some troubles with geting single user basing on his ID. I can remove this certain user with DELETE in my app but I can't get informations about him using "GET".
this is my angular app.js
app.controller('editUser', function($scope, $http, $state) {
$http.get('users/editUser/'+$state.params.userId).success(function(data) {
console.log(data);
});
});
and this is my users.js routes file
router.get('/editUser/:userId', ensureAuthenticated, function(res, req, next) {
var userId= req.params.userId,
data;
getUser.findOne({'_id': userId}, function(err, user) {
if(err) throw err;
data = user;
res.json(data);
});
});
after clicking on "edit" button I am redirected to users/editUser/ffw23rfaw - its id, and basing on this id I use get function to get info about him but I get 500 "Internal server error". I would like to add that removing user is pretty much same and it works.
after clicking Edit button I do this
$scope.editUser = function($index) {
$state.go('editUser', {userId: $index});
}
that's how I get userId on 'users/editUser/' page
and this is my state config
.state('editUser', {
url: '/users/editUser/:userId',
templateUrl: '/views/editUser.html'
})
Found out the issue :)
Your code has function(res, req, next)
Change that to
function(req, res, next)
just wrong placement of parameters (variable names).
Hope this helps. (thanks for pointing out the console message)
Related
The existing code was written as MySQL query and I am now working on converting it to Mongoose query.
I need to get five data sorted by the most recent subscription year from the main page.
The existing code brought this result value into an array. And data was delivered through pug view, and Mongoose seems to bring the result value of Object. In this case, I wonder how to deliver the data through Pug view.
I checked importing data from the terminal to the console.log, but an error called 'Error [ERR_HTTP_HEADERS_SENT]: Cannot set heads after they are sent to the client occurs and no data is passed to the pug. I wonder why this problem occurs.
[MySQL Query]
router.get("/", function (req, res, next) {
// Main page Profile Data Process
db.query(`SELECT * FROM user ORDER BY registerDate DESC LIMIT 5`, function (
error,
data
) {
// Log Error
if (error) {
console.log(error);
}
res.render("main", {
dataarray: data,
_user: req.user,
url: url
});
});
});
[Mongoose Query]
router.get("/", function (req, res, next) {
let dataarray = [];
let userData = db.collection("user").find().limit(5).sort({
"created_at": -1
});
userData.each(function (err, doc) {
if (err) {
console.log(err);
} else {
if (doc != null) {
dataarray.push(doc)
}
}
// console.log(dataarray.login)
console.log(dataarray);
res.render("main", {
dataarray,
_user: req.user
})
});
});
[pug file]
each profile in dataarray
.col-lg-4
img.rounded-circle(src=`${profile.avatar_url}` alt='Generic placeholder image' width='140' height='140')
h2=`${profile.login}`
p=`${profile.bio}`
p
a.btn.btn-secondary(href=`/${profile.login}` role='button') View details ยป
You are sending the request in multiple chunks, node/express uses one request and one response.
Cannot set heads after they are sent to the client
Is the error that happens when the res.render is called the second time. At this point, the one request has already left the node/express process and this is tell you that you're trying to violate the one request/one response paradigm.
This is the part of your code where you can see why this happens.
router.get("/", function (req, res, next) {
let dataarray = [];
let userData = db.collection("user").find().limit(5).sort({
"created_at": -1
});
userData.each(function (err, doc) {
This part of your code will try to send a response for each item in your resultset.
Something like this will work properly (I didn't test it):
router.get("/", function (req, res, next) {
db.collection("user").find().limit(5).sort({ "created_at": -1 }, function(err, userData){
res.render("main", {
dataarray: userData,
_user: req.user
})
});
});
In other words, only one res.render is required and pass the entire result set into that.
i am getting started with node.js and now I got stuck.
var mysql = require('mysql');
var dbconfig = require('../config/database');
var connection = mysql.createConnection(dbconfig.connection);
connection.query('USE ' + dbconfig.database);
app.get('/createarticle', isLoggedIn, function(req, res){
res.render('createarticle.ejs', {
user:req.user
});
});
app.post('/createarticle' , (req, res ) => {
let sql = 'INSERT INTO news SET ?'
let post = {
// author: req.user.username,
content : req.body.content,
title: req.body.title
}
connection.query(sql, post, (err, res) => {
if(err) throw err;
console.log('success');
console.log(res);
});
});
If I use req.user.username I get this error message Cannot read property 'username' of undefined.
I also tried user.username and req.user.
In my main JS I have this function that shoud always give the user if logged in.
app.get('*', function(req, res, next) {
res.locals.user = req.user || null;
next();
});
In addition to this I want to include two redirects but I don't know where to put it.
successRedirect: '/',
failureRedirect: '/createarticle',
I appreciate every answer and pacience with me. :)
I can't comment so I have to post an answer:
What does your request object look like:
app.get('/createarticle', isLoggedIn, function(req, res){
console.log('request',req)
res.render('createarticle.ejs', {
user:req.user
});
});
If you're not populating the request object in your 'GET' from your front end,
you won't have the user you are asking for.
You may want to do some handling in the front to make sure that you only send populated request objects.
Very confused and not sure if I am thinking about it correctly. Please let me know what else I need to show for this to make sense...
I have two different functions in mongoose. One indexes all listings and the other indexes unique user listings and is filtered in my mongoose function. However, in my routes, how do I hit the unique function when on my profile page if the $http url is the same?
//From server.js to controllers
app.get('/api/listings', controllers.listings.index);
//all listings shown on home page
function index (req, res) {
db.Listing.find({}, function(err, allListings) {
res.json(allListings);
});
}
//From server.js to controllers
app.get('/api/listings/', auth.ensureAuthenticated, controllers.profiles.indexUnique);
//unique function that I want to show on profile page only
function indexUnique(req, res) {
db.User.findById(req.user, function (err, user) {
if (err) {console.log(err);}
db.Listing.find({uid: req.user}, function(err, listings) {
if(err) { console.log('Error', err); }
res.json(listings);
});
})
}
How do I adjust my http request to hit my unique function if the url routes are the same?
// Angular http request in my home controller
$http({
method: 'GET',
url: '/api/listings'
}).then(function successCallback(response) {
vm.listings = response.data;
}, function errorCallback(response) {
console.log('Error getting data', response);
});
you could do the filtering on angular as a service and keep two separate arrays of objects
I have a function that runs on a click, I want this click to redirect to a other view. like a simple link.
how can I render a new view onclick?
node
router.post('/shareinsight', function(req, res, next) {
console.dir(req.body)
var db = req.db_login;
console.log('fs' + req.body.date)
res.redirect('contact');
});
I can see the log in the console so I know that the function is running but it doesn't change view
Try to use this code:
router.post('/shareinsight', function(req, res, next) {
console.dir(req.body)
var db = req.db_login;
console.log('fs' + req.body.date)
res.writeHead(302, {
'Location': 'url'
});
res.end();
});
I am making a wikipedia clone for a project. My initial edit Route looks like this:
router.get('/edit/:id', function(req, res){
var id = req.params.id;
console.log(id);
models.Page.findById(id, function(err, doc){
console.log(doc);
res.render('edit', {page: doc});
});
});
All I am doing is creating an edit page view for a Page with matching id of the id params.
This works until...
I had to add this new route:
router.get('/:url_name/:id', function(req,res){
var id = req.params.id;
models.Page.findById(id, function(err, doc){
res.render('show_page', {page: doc});
});
});
Now when I have this route active, my edit/:id page route doesn't collect the id parameter(req.params.id).
I am lost on why this isn't working and where I should start trying to debug because I am not getting any errors, it will still take me to my edit/:id page, but when I console.log(id) I do not receive a value, or even and undefined, nothing. Furthermore, the {page:doc} I am passing to my edit view is not being found.
If anyone can provide insight or a place to start looking to debug, I'd appreciate it. Just a reminder, the edit/:id route works as it should (req.params.id grabs the id) when I don't have the :url_name/:id route active.
Current Routes -
I added var wiki_routes = require('./routes/wiki'); in my app.js and in that route I have:
// **** URL ROUTES ****
router.get('/', function(req, res) {
models.Page.find(function(err, docs) {
res.render('index', { docs: docs });
});
});
router.get('/:url_name', function(req, res){
var url_name = req.params.url_name;
var isUpdated = req.query.updated;
var updated = (isUpdated === 'true')?true:false;
models.Page.find({url_name: url_name}, function(err, page){
if(page.length > 1){
console.log(page);
res.render('disambiguation', {pages: page, updated: updated });
} else {
console.log(page);
res.render('show_page', {page: page[0], updated: updated});
}
});
});
router.get('/:url_name/:id', function(req,res){
var id = req.params.id;
models.Page.findById(id, function(err, doc){
res.render('show_page', {page: doc});
});
});
// **** EDIT ROUTES ****
router.get('/edit/:id', function(req, res){
var id = req.params.id;
console.log(id);
models.Page.findById(id, function(err, doc){
console.log(doc);
res.render('edit', {page: doc});
});
});
router.post('/edit_submit/:id', function(req, res){
var id = req.params.id;
var new_title = req.body.title;
var new_body = req.body.body;
console.log(req.body);
models.Page.findByIdAndUpdate(id, {title: new_title, body: new_body }, function(err, docs){
// redirects to the wiki page
res.redirect('/wiki/'+ docs.url_name +'?updated=true');
});
});
// **** DELETE ROUTE ****
router.get('/delete/:id', function(req, res){
var id = req.params.id;
models.Page.findByIdAndRemove(id, function(err, data){
res.redirect('/?deleted=true');
});
});
Routes are set up as they occur in the code, as node will give presedence to whichever route it encounters first, so order matters a lot when you're setting up your routes.
An URL could potentially match several routes, especially when using variables that catch a large number of different URL's, or static routes etc.
Say in your case you have an URL that looks like
http://example.com/edit/1234
That URL would most certainly be caught by this route
router.get('/:url_name/:id' ....
as it matches the http://example.com/something/something layout, and it would also be caught by the following route
router.get('/edit/:id', ....
as it matches the http://example.com/edit/something layout.
What route actually cathes the URL depends on the order they where encountered when set up, whichever route that was declared first will catch the URL.
Just shifting the order of the routes will in most cases solve issues like this
// if the URL matches, this will execute first
router.get('/edit/:id', function(req, res){
// do stuff
});
// You'll only get here if the URL doesn't match the above route
router.get('/:url_name/:id', function(req, res){
// do stuff
});
There is a workaround if you simply can't swap the routes around, using the next() callback, like this
router.get('/:url_name/:id', function(req, res, next){
if ( req.params.url_name == 'edit' ) {
next(); // this sends the request back to look for routes below this one
}else{
// do stuff
}
});
router.get('/edit/:id', function(req, res){
// now we'll get here when the "url_name" is "edit" ...
});