0

I have a simple nodejs app with some users. I want to load a specific user profile using a URL localhost/users/(username) but I'm getting this error when I try to load the URL:

Cannot GET /users/test

Here's my user.js routes file for the user page:

var express = require('express');
var router = express.Router();
var User = require('../models/user');

// GET user by username
router.get('/users/:username', function(req, res) {
  var username = req.params.username;
  res.send(req.params);
  res.render('user');
});

module.exports = router;

I have a user.handlebars file in my views folder so it should load the file. What am I missing in my routes file? Any help would be greatly appreciated. Thanks!!

EDIT: app.js:

console.log('Starting app.js');

const fs = require('fs');
const _ = require('lodash');
const express = require('express');
const path = require('path');
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');
const exphbs = require('express-handlebars');
const expressValidator = require('express-validator');
const flash = require('connect-flash');
const session = require('express-session');
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const mongo = require('mongodb');
const mongoose = require('mongoose');

mongoose.connect('mongodb://localhost/tipcup');
var db = mongoose.connection;

const routes = require('./routes/index');
const users = require('./routes/users');
const user = require('./routes/user');

// Init App
var app = express();

// View Engine
app.set('views', path.join(__dirname, 'views'));
app.engine('handlebars', exphbs({defaultLayout: 'layout'}));
app.set('view engine', 'handlebars');

// BodyParser middleware
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false}));
app.use(cookieParser());

// Set Static Folder
app.use(express.static(path.join(__dirname, 'public')));

// Express Session
app.use(session({
  secret: 'secret',
  saveUninitialized: true,
  resave: true
}));

// Passport Init
app.use(passport.initialize());
app.use(passport.session());

// Express Validator
app.use(expressValidator ({
  errorFormatter: function(param, msg, value) {
    var namespace = param.split('.')
    , root = namespace.shift()
    , formParam = root;

    while(namespace.length){
      formParam += '[' + namespace.shift() + ']';
    }
    return {
      param: formParam,
      msg: msg,
      value: value
    };
  }
}));

// Connect Flash
app.use(flash());

// Global Vars
app.use(function (req, res, next){
  res.locals.success_msg = req.flash('success_msg');
  res.locals.error_msg = req.flash('error_msg');
  res.locals.error = req.flash('error');
  res.locals.user = req.user || null;
  next();
});

app.use('/', routes);
app.use('/users', users);
app.use('/users/:username', user);

// Set Port
app.set('port', (process.env.PORT || 3000));

app.listen(app.get('port'), function(){
  console.log('Server started on port '+app.get('port'));
});
2
  • did you use any middleware in app.js? Commented Feb 3, 2018 at 14:43
  • yes, I do. Sorry I forgot to post it. Updating question now Commented Feb 3, 2018 at 14:44

1 Answer 1

1

Render function renders a view and sends the rendered HTML string to the client.Take a look at documentation. But what you are trying to archive is to send data first and then render and send again. So, just delete the line with send.

router.get('/users/:username', function(req, res) {
  var username = req.params.username;
  res.render('user');
});

And, please, edit your question by adding your code with middleware and add your error.

Update

Take a look at the way how you define your routes for users. You have to remove /users from defining route in users.js file

Sign up to request clarification or add additional context in comments.

7 Comments

Thanks for the answer! I removed the line but I'm still getting the error. I updated the question with my app.js middleware. The error I'm getting is cannot GET /users/test
Yes, I've noticed. Take a look at my update, or the answer below. As a result, in your app, you have users/users/:username.
When you make app.use('/users', users) It's like adding this string /users in front of all routes that are exist in the file users.js
Nope. The idea is to define your scope of routes. For example, if inside app.js you have app.use('/users', users), it means that inside users.js file you should have only '/:username'
But, also, I've noticed that you will have the situation when you will not reach your routes in user.js because it's duplicating with routes for users that are defined first. The answer for this is to define routing for specific user in this way app.use('/user', user)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.