jQuery Not Working in Express JS - NodeJS - javascript

Ok, so I'm new to Express. I'm messing around with sessions and ajax calls, but the problem I'm having is that whenever I run my app, my jquery doesn't work for some reason. This is the code I have:
app.js
var express = require("express");
var mongoose = require("mongoose");
var bodyParser = require("body-parser");
var session = require('express-session')
var app = express();
app.use(express.static("public")); // I understand this is the directory where I would need to put all my static files: css, js, images, etc.
app.set("view engine", "jade");
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
//Set secre pass for the session
app.use(session({secret:'password'}));
app.get("/",function(req, res){
if(req.session.userName){
res.render("admin", {session_name: req.session.userName});
}else{
res.render("home");
}
});
app.post("/example-ajax", function(req, res){
res.send(req.body.email); // return the email that was sent by the client
});
app.post("/log-in", function(req, res){
req.session.userName = req.body.name;
res.redirect("/");
});
app.get("/log-out", function(req, res){
req.session.destroy();
res.redirect("/");
});
app.listen(8080);
admin.jade
extends layout_head.jade
block content
div(class="container")
div(class="row")
div(class="col-lg-6 col-lg-offset-3")
h1 Logged In!!
h3 Logged in as: #[b #{session_name}]
a(href="/log-out") Log Out
br
div(class="btn btn-info testAjax") Test Ajax
script(src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js")
script(href="/css/bootstrap/js/bootstrap.min.js")
script(href="/js/main.js")
main.js
$(document).ready(function(){
alert("Loaded");
$(".testAjax").on("click", function(){
alert("test");
$.ajax({
type: 'POST',
url: '/example-ajax',
data: {
email: "admin#yahoo.com"
},
success: function(data){
// data = the email being returned from the server
console.log("Your email is: " + data);
}
});
});
});
So like I said, the jquery doesn't run whenever my page loads up or when I click the testAjax button. When I check the console, it doesn't give me any errors so I don't know what is causing the problem.
My second question is: Is this the right way to make ajax calls in Express?
Any help is greatly appreciated. Thanks.

I just needed to change href to src in the script tags.

Related

Javascript code not running on PUG/Jade file

I'm following this tutorial to implement a tic tac toe game using socket.io:
https://ayushgp.github.io/Tic-Tac-Toe-Socket-IO/ .
But I also want to use a login system.
When the user logs in, it successfully goes to this page (I converted html to pug), located on /views/game.pug
doctype html
html
head
title Tic Tac Toe
link(rel='stylesheet', href='/css/main.css')
link(rel='stylesheet', href='/node_modules/skeleton-css/css/skeleton.css')
body
.container
.menu
h1 Tic - Tac - Toe
h3 How To Play
ol
li Player 1 Create a new game by entering the username
li
| Player 2 Enter another username and the room id that is displayed on first window.
li Click on join game.
h4 Create a new Game
input#nameNew(type='text', name='name', placeholder='Enter your name', required='')
button#new New Game
br
br
h4 Join an existing game
input#nameJoin(type='text', name='name', placeholder='Enter your name', required='')
input#room(type='text', name='room', placeholder='Enter Game ID', required='')
button#join Join Game
.gameBoard
h2#userHello
h3#turn
table.center
tr
td
button#button_00.tile
td
button#button_01.tile
td
button#button_02.tile
tr
td
button#button_10.tile
td
button#button_11.tile
td
button#button_12.tile
tr
td
button#button_20.tile
td
button#button_21.tile
td
button#button_22.tile
.container
script(src='/node_modules/jquery/dist/jquery.min.js')
script(src='/socket.io/socket.io.js')
script(src='/js/main2.js')
That works fine. But when I click the button with id #new, nothing happens.
This is the error I get: https://i.imgur.com/83p72Ag.png .
This is the relevant part of main2.js, located on /public/js/main2.js:
$('#new').on('click', () => {
const name = $('#nameNew').val();
if (!name) {
alert('Please enter your name.');
return;
}
socket.emit('createGame', { name });
player = new Player(name, P1);
});
EDIT:
Files' locations:
main.css on /public/css/main.css
skeleton.css on /node_modules/skeleton-css/css/skeleton.css
jquery.min.js on /node_modules/jquery/dist/jquery.min.js
socket.io.js on /node_modules/socket.io-client/dist/socket.io.js
main2.js on /public/js/main2.js
app.js (only relevant parts are shown):
const express = require('express');
const path = require('path');
const app = express();
const server = require('http').Server(app);
const io = require('socket.io')(server);
app.use(express.static('.'));
//Load View engine
app.engine('pug', require('pug').__express);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
//Set public folder
app.use(express.static(path.join(__dirname, 'public')));
//This get request is sent after the user logs in. It works fine
app.get('/users/game', function(req, res) {
res.render('game', {
title:'Game'
});
});
io.on('connection', (socket) => {
//See full code here:https://github.com/ayushgp/tic-tac-toe-socket-io/blob/master/index.js
}
let articles = require('./routes/articles');
let users = require('./routes/users');
app.use('/articles', articles);
app.use('/users', users);
Also, my main2.js file is identical to this one: https://github.com/ayushgp/tic-tac-toe-socket-io/blob/master/main.js
EDIT2:
Full app.js code (the relevant part is the get request to users/game:
const express = require('express');
const path = require('path');
const app = express();
const server = require('http').Server(app);
const io = require('socket.io')(server);
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const expressValidator = require('express-validator');
const flash = require('connect-flash');
const session = require('express-session');
const config = require('./config/database');
const passport = require('passport');
let rooms = 0;
app.use(express.static('.'));
mongoose.connect(config.database, {
useMongoClient: true
});
let db = mongoose.connection;
//Check connection
db.once('open', function(){
console.log('Connected to MONGOdb')
});
//Check for DB errors
db.on('error', function(err){
console.log(err);
});
//Bring in models
let Article = require('./models/article');
//Load View Engine
app.engine('pug', require('pug').__express);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
// Boddy parser middlware
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
//Set public folder
app.use(express.static(path.join(__dirname, 'public')));
//Express Session Middleware
app.set('trust proxy', 1) // trust first proxy
app.use(session({
secret: 'keyboard cat',
resave: true,
saveUninitialized: true,
cookie: { secure: false }
}));
//Express Messages Middleware
app.use(require('connect-flash')());
app.use(function (req, res, next) {
res.locals.messages = require('express-messages')(req, res);
next();
});
//Express Messages Middleware
app.use(expressValidator());
//Passport Config
require('./config/passport')(passport);
//Passport Middleware
app.use(passport.initialize());
app.use(passport.session());
app.get('*', function(req, res, next){
res.locals.user = req.user || null;
next();
});
//Home ROute
app.get('/', function(req, res) {
Article.find({}, function(err, articles){
if(err){
console.log(err);
} else {
res.render('index', {
title:'Articles',
articles: articles
});
}
});
});
app.get('/users/game', function(req, res) {
res.render('game', {
title:'Game'
});
});
io.on('connection', (socket) => {
// Create a new game room and notify the creator of game.
socket.on('createGame', (data) => {
socket.join(`room-${++rooms}`);
socket.emit('newGame', { name: data.name, room: `room-${rooms}` });
});
// Connect the Player 2 to the room he requested. Show error if room full.
socket.on('joinGame', function (data) {
var room = io.nsps['/'].adapter.rooms[data.room];
if (room && room.length === 1) {
socket.join(data.room);
socket.broadcast.to(data.room).emit('player1', {});
socket.emit('player2', { name: data.name, room: data.room })
} else {
socket.emit('err', { message: 'Sorry, The room is full!' });
}
});
/**
* Handle the turn played by either player and notify the other.
*/
socket.on('playTurn', (data) => {
socket.broadcast.to(data.room).emit('turnPlayed', {
tile: data.tile,
room: data.room
});
});
/**
* Notify the players about the victor.
*/
socket.on('gameEnded', (data) => {
socket.broadcast.to(data.room).emit('gameEnd', data);
});
});
//Route files
let articles = require('./routes/articles');
let users = require('./routes/users');
app.use('/articles', articles);
app.use('/users', users);
//Start Sever
app.listen(3000, function() {
console.log('Server running');
});
The code block will not working:
script(src='node_modules/jquery/dist/jquery.min.js')
please try like this:
app.use('/scripts',
express.static(path.join(__dirname, 'node_modules/jquery/dist')),
// add some others
);
app.use('/styles',
express.static(path.join(__dirname, '/node_modules/skeleton-css/css')),
// add some others
);
On view:
script(src='/scripts/jquery.min.js')
link(type='text/stylesheet' href='/styles/skeleton.css')
And you don't need the socket-io-client module for socket client.
On your code block, if you want the socket connection of the same original host, you don't need the socket-io-client module.
if you have created the socket server using socket.io, you can include the socket.io script like this when using view template.
script(type='text/javascript', src='/socket.io/socket.io.js')
Based on your console screen grab, there are at least two problems here:
Your server-side route (if you even have one) for script(src='node_modules/jquery/dist/jquery.min.js') is not working so jQuery never loads in the web page. Thus, no attempt to use jQuery works.
Your socket.io server is not started or initialized properly on the server.
To be able to suggest fixes, we'd need to see the relevant server-side code and we'd need to know where all resources referenced in game.pug are located in your server-side file system (full path). You are either missing route a definition for the jQuery file or there's an error in the route definition.
It does look like main2.js is loading properly, though it immediately encounters an error because of the missing jQuery.
FYI, using script paths like this:
script(src='/node_modules/jquery/dist/jquery.min.js')
is generally not considered a good practice because it exposes and ties you to a specific server-side file structure. In general, you would do something like this instead:
app.use("/jquery", express.static(path.join(__dirname, "/node_modules/jQuery/dist")));
And, then use this in the client:
script(src='/jquery/jquery.min.js')
Now, the ONLY directory you've exposed to the public is /node_modules/jQuery/dist and you've not created a hard link between client web pages and server-side file structure.
You would repeat that process for each dist directory that you need to draw from. The way you have it now, you have granted public access to your entire node_modules server-side directory which is NOT something you want to do.
Also, when your socket.io server is working appropriately on the server, then it has a built-in route for socket.io.js. You can just use this in the client:
script(src='/socket.io/socket.io.js')
And, the socket.io server will automatically server the socket.io.js from that route. You don't have to manually create a route for that.
To get socket.io working properly, change this;
//Start Sever
app.listen(3000, function() {
console.log('Server running');
});
to this:
//Start Sever
server.listen(3000, function() {
console.log('Server running');
});
In these two lines of code, you created a web server and bound socket.io to it:
const server = require('http').Server(app);
const io = require('socket.io')(server);
But, then with app.listen(), you created a different web server and started it and never started the one that socket.io is connected to. Instead, you want to use server.listen(...) to start the one that you attached socket.io to.

Node.js send data to backend with AJAX

I'm quite new to AJAX, so sorry for potential missunderstandings, but I'm not completely through that thing.
I'm trying a simple thing. I have a server.js file, which is my backend basically. Then I have a index.html and a script.js. That's all, so a very basic setup. Now, on my script.js, I'm getting some data (a mail address). Now I want to send that data to my backend (into the server.js) to work with it there. How can I do this?
I found some posts already about AJAX with node.js, but I don't get it, especially not where to receive it in my backend. I'm using express for the server by the way.
What I have in my script.js is:
$.ajax({
type: "POST",
url: "server.js",
data: { mail: mail },
success: function(data) {
},
error: function(jqXHR, textStatus, err) {
alert('text status '+textStatus+', err '+err)
}
});
Right so far? How can I now receive the information in my server.js?
There's not much in so far, just:
var express = require('express');
var app = express();
var server = app.listen(3000);
app.use(express.static('public'));
Thanks for any help :)
Note: This was written before the question was updated with the code so the field names and port numbers that I used here as examples may need to be updated with the correct values.
Client-side code - example with jQuery:
$.post('/email', { address: 'xxx#example.com' });
(this can take optional callbacks and it returns a promise that can be used to add a success/error handler)
Server-side code - example with Express:
const express = require('express');
const bodyParser = require('body-parser');
const dir = path.join(__dirname, 'public');
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.post('/email', (req, res) => {
// you have address available in req.body:
console.log(req.body.address);
// always send a response:
res.json({ ok: true });
});
app.use(express.static(dir));
app.listen(4443, () => console.log('Listening on http://localhost:4443/'));
This assumes that your static files (HTML, client-side JavaScript, CSS) are in the public directory relative to your server.js file.
See this for background on the JSON/form-encoding issue:
Which method is prefer when building API
See this for background on serving static files:
How to serve an image using nodejs
That's actually quite simple to implement in Express.JS with the basic router:
I'm gonna give you the minified code snippets to help you get sense of how it works across browser and server.
in Front-End, you basically just want to "post" an email address to the backend:
$.post('/email', { email: 'howareyou#xx.com' })
and in Back-End(Express.JS), you should implement the basic router:
var express = require('express');
var app = express();
// use: app.METHOD(PATH, HANDLER)
app.post('/email/', function(req, res) {
var email = req.body.email
})
Read more here: http://expressjs.com/en/guide/routing.html
First, you need a valid route to hit when the server is running. You can do this in server.js through express.
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.json());
app.use(express.static('public'));
app.post('/mail', function(req, res) {
var body = req.body;
console.log('email', body.email);
res.json({ message: 'I got the email!' });
});
var server = app.listen(3000);
Notice I have brought in an express middleware that will parse the body for JSON and make it available on the req object under req.body. You will need to install this dependency with npm install --save body-parser.
Then you need to send a POST request to that URL from the front-end.
$.ajax({
type: "POST",
url: "/mail",
data: { mail: mail },
success: function(data) {
console.log('message', data.message);
},
error: function(jqXHR, textStatus, err) {
alert('text status '+textStatus+', err '+err)
}
});
Now, if you submit an email, you should see a log in your terminal that shows the email and a log in your developer console in the browser that shows the message "I got the email!"
in server.js add this :
app.post('/searching', function(req, res){
//do something with req
});
and in script.js :
$.ajax({
type: "POST",
url: "/searching",
data: { mail: mail },
success: function(data) {
},
error: function(jqXHR, textStatus, err) {
alert('text status '+textStatus+', err '+err)
}
});
First of all you nedd to create a route for the Mail
var express = require('express');
var path = require('path');
var bodyParser = require('body-parser');
var app = express();
var router=app.Router();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false })); // Parse request body
app.use(express.static(path.join(__dirname, 'public')));
// Route to check Email
router.post('/CheckEmail',(req,res)=>{
var email=req.body.mail; // Get email here
})
app.listen(process.env.port || 3000,()=>{
console.log('server is running');
})
Ajax
$.ajax({
type: "POST",
url: "/CheckEmail", // post route name here
data: { mail: mail },
success: function(data) {
},
error: function(jqXHR, textStatus, err) {
alert('text status '+textStatus+', err '+err)
}
});
You need a few more things to actually be able to parse the body. Add this to your server.js file.
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
You need to specify a valid URL. Since you are listening on 3000. You also need to specify a route on your server as an endpoint.
$.ajax({
type: "POST",
url: "http:localhost:3000/",
data: { mail: mail },
success: function(data) {
},
error: function(jqXHR, textStatus, err) {
alert('text status '+textStatus+', err '+err)
}
});
Now you need to add a route on your server. You can do so by adding this to your server.js file after all of the app.use calls
app.post("/", function(req, res){
// your logic here
res.send("I am sending something back!");
})

Sending json with $.post in express/node

This is my app.js file:
var express = require('express');
var app = express();
var path = require('path');
var $ = require('jquery');
var nodemailer = require('nodemailer');
app.use('/static', express.static(path.join(__dirname, 'static')));
app.get('/', function(req, res) {
res.sendFile('./views/index.html', {"root": __dirname});
});
app.post('/contact/', function(req, res){
console.log(req.body);
});
and my post request from another file, which is called when a form is submitted:
$('form').submit(function(e){
e.preventDefault();
var content = $('#message').val();
var email = $('#EmailInput').val();
var reason = $('#reason').val();
$.post('/contact', { 'content': content, 'email': email, 'reason': reason }, function(data){
console.log(data);
});
})
However, whenever the form is submitted, the post request is successful, it's just no data has been passed.
req and req.body both return undefined. I can't figure out why.
you need the body parser to populate the body property of the request object
npm install body-parser
then include
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
documentation for your particular use case and tweaking may be found here
edit: be sure to include this BEFORE your route handlers are declared

Angularjs Ajax Post to Epressjs

I am trying to make a Ajax request from Angularjs to Express js. Below code is my angularjs and express js route.
The problem is I am getting 500 Server error when I make a POST and get seems to work without any problem
AngularJs code
$http.post('http://www.mydomin.com/abc',str)
.success(function(data) {
alert(data);
})
.error(function(data) {
alert(1);
});
Here str can be just a letter or anything str= 't'; for example
ExpressJs route
module.exports = function(app) {
app.post('/abc', function(req, res) {
console.log('ggg');
});
};
This route is added to app.js as well
require('./routes/test')(app);
Try changing your code to something like this:
$http.post('/abc',{name: str})
.success(function(data) {
alert(data);
})
.error(function(data) {
alert(1);
});
app.js
var express = require('express');
var app = express.createServer();
app.configure(function(){
app.use(express.json());
app.use(express.urlencoded());
});
require('./routes/test')(app);
app.listen(3000);
routes/test.js
module.exports = function(app){
app.post('/abc', function(req, res){
console.log(req.body);
res.send("ok");
});
}
This is a really basic app that should work without issue. Not sure where you are differing, but this is a bsic template to go off of.

Node.js express POST 404ing

I've got a small node.js application using the express framework, but for some reason I can't get my application to respond to POST requests. In the server log I simply get "POST / 404 5ms", and I can't figure out why.
EDIT: To clarify - My problem is that app.post doesn't seem to be doing anything
EDIT 2: I somehow managed to fix this last night, but now I can't figure out at what point i fixed it.
Node.js server code:
var express = require('express')
, routes = require('./routes')
, user = require('./routes/user')
, http = require('http')
, path = require('path');
var app = express();
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.cookieParser('chocolatechip'));
app.use(express.session());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
//pages
//Landing page
app.get('/', routes.index);
app.post('/test',function(req,res){
console.log(req.body);
res.send("received post");
});
//return list containing users
//app.post('/users', user.list);
//return requested user
app.get('/users/:id', user.get);
//app.post('/users/login', user.login);
//server
http.createServer(app).listen(app.get('port'), function(){
console.log('Server listening on port ' + app.get('port'));
});
On the actual webpage, I've got the following javascript code:
var login = $('#login');
var page = $('#page');
var register = $('#register');
var userField = login.find('.user');
var passField = login.find('.pass');
var confPassField = login.find('.confpass');
var form = $('.logform');
$('#formbutton').on('click',function(){
if(register.hasClass('hidden')){
login.addClass('hidden');
confPassField.val('');
var logDat = JSON.stringify(form.serializeArray);
userField.val('');
passField.val('');
page.html("Login form submitted");
$.post(
form.attr("action"),
{test:"test"},
function(data){
alert("Response: "+data)
}
);
}
If you are posting to / as your log is saying that you are "POST / 404 5ms", you need to change the following line:
app.get('/', routes.index);
to
app.all('/', routes.index);
This will allow a GET or POST to that route. You can also just use app.post() if you are only posting to that route. Hope this helps.
Docs here: http://expressjs.com/api.html#app.all
Make sure that 'form.attr("action")' is getting the proper URL. It seems that your form is posting to the index page rather than to '/test'. Maybe that should be changed to $('form').attr("action")
For me the problem was that I had my
app.post('/test', jsonParser, function (req, res) {
console.log(req);
res.send('Ok');
});
below this part added by express-generator to my app.js
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
By changing the order in the file I resolved this problem.

Categories