I am learning NodeJS by following tutorials available online. Recently, I am working on a Decision making system that usis Twitter Sentimental analysis to conclude a choice. I am using Express and Node.js to complete the application. I have followed the tutorial and completed the application. However, I cant make it run.
I tried debugging the code and found that my Jquery.post()
is not functioning correctly. The debugger is not making a call to $.post
or ajax method. As a result, my "/search"
route is not calling. After clicking the Decision button, the system does not perform anything. The following is the code for the application.
index.jade
title= title
meta(charset='utf-8')
meta(name='viewport', content='width=device-width, initial-scale=1.0')
meta(name='description', content='')
meta(name='author', content='Michael Herman')
link(href='http://netdna.bootstrapcdn.com/bootswatch/3.1.0/yeti/bootstrap.min.css', rel='stylesheet', media='screen')
link(href='/stylesheets/main.css', rel='stylesheet', media='screen')
body
.container
.jumbotron
h1 Need to make a decision?
p.lead Use Twitter sentiment analysis.
br
br
.form-container
form(action='', method='post')
input#choice1.choice(type='text', data-choice='1', placeholder='Choice #1...', name='choice1')
input#choice2.choice(type='text', data-choice='2', placeholder='Choice #2...', name='choice2')
input#decision.btn.btn-success.btn-lg(type='submit', value='Decide!')
br
br
.decision-container
p#status
p#decision-text
p#score
input#again.btn.btn-success.btn-lg(value='Again?')
script(src='http://code.jquery.com/jquery-1.11.0.min.js')
script(src='http://netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js')
script(src='javascripts/main.js')
app.js
var express = require('express');
var routes = require('./routes');
var http = require('http');
var path = require('path');
var fs = require('fs');
var favicon = require('serve-favicon');
var logger = require('morgan');
var bodyParser = require('body-parser');
var app = express();
app.set('views', path.join(__dirname, 'views'));
app.use(logger('dev'));
app.set('view engine', 'jade');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, 'public')));
// routes
app.get('/', routes.index);
app.get('/ping', routes.ping);
app.post('/search', routes.search);
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
module.exports=app;
Index.js
var path = require("path");
var twit = require('twit');
var sentimental = require('Sentimental');
exports.index = function(req, res){
res.render('index', { title: "Twit-Decision"});
};
exports.ping = function(req, res){
res.send("pong!", 200);
};
exports.search = function(req, res) {
// grab the request from the client
var choices = JSON.parse(req.body.choices);
// grab the current date
var today = new Date();
// establish the twitter config (grab your keys at dev.twitter.com)
var twitter = new twit({
consumer_key: *******,
consumer_secret: *******Dbb0dx7Si4,
access_token: ********t5bJmk,
access_token_secret: *******lk
});
// set highest score
var highestScore = -Infinity;
// set highest choice
var highestChoice = null;
// create new array
var array = [];
// set score
var score = 0;
console.log("----------")
// iterate through the choices array from the request
for(var i = 0; i < choices.length; i++) {
(function(i) {
// add choice to new array
array.push(choices[i])
// grad 20 tweets from today
twitter.get('search/tweets', {q: '' + choices[i] + ' since:' + today.getFullYear() + '-' +
(today.getMonth() + 1) + '-' + today.getDate(), count:20}, function(err, data) {
// perfrom sentiment analysis (see below)
score = performAnalysis(data['statuses']);
console.log("score:", score)
console.log("choice:", choices[i])
// determine winner
if(score > highestScore) {
highestScore = score;
highestChoice = choices[i];
console.log("winner:",choices[i])
}
console.log("")
});
})(i)
}
// send response back to the server side; why the need for the timeout?
setTimeout(function() { res.end(JSON.stringify({'score': highestScore, 'choice': highestChoice})) }, 5000);
};
function performAnalysis(tweetSet) {
//set a results variable
var results = 0;
// iterate through the tweets, pulling the text, retweet count, and favorite count
for(var i = 0; i < tweetSet.length; i++) {
tweet = tweetSet[i]['text'];
retweets = tweetSet[i]['retweet_count'];
favorites = tweetSet[i]['favorite_count'];
// remove the hashtag from the tweet text
tweet = tweet.replace('#', '');
// perfrom sentiment on the text
var score = sentimental.analyze(tweet)['score'];
// calculate score
results += score;
if(score > 0){
if(retweets > 0) {
results += (Math.log(retweets)/Math.log(2));
}
if(favorites > 0) {
results += (Math.log(favorites)/Math.log(2));
}
}
else if(score < 0){
if(retweets > 0) {
results -= (Math.log(retweets)/Math.log(2));
}
if(favorites > 0) {
results -= (Math.log(favorites)/Math.log(2));
}
}
else {
results += 0;
}
}
// return score
results = results / tweetSet.length;
return results
}
Main.js
$(function () {
// highest # of choices (inputs) allowed
window.highestChoice = 2;
// hide again button on page load
$("#again").hide();
var goDecide = function(e) {
// prevent default browser behavior upon submit
e.preventDefault();
console.log("--------------- Inside GODECIDE----------------");
// erase old values
$("#status").text('');
$("#score").text('');
// hide decision text
$("#decision-text").hide();
$("#again").hide();
// display processing text, update color to black in case of an error
$("#status").css("color", "black");
$("#status").text("Processing ...");
// create variable to see if any of the inputs are input
var anyEmpty = false;
// array to hold inputs
var choices = [];
// grab values, add to choices array
for(var i = 1; i <= window.highestChoice; i++) {
var choiceValue = $("#choice"+i).val();
if(choiceValue == '') {
anyEmpty = true;
} else {
if(choices.indexOf(choiceValue) == -1) {
choices.push(choiceValue);
}
}
}
console.log("--------------- CHOICES LOOP COMPLETED---------------");
// Handling *some* errors
if(!anyEmpty) {
if($("#choice1").val() != $("#choice2").val()) {
// send values to server side for processing, wait for callback, getting AJAXy
$.ajax({
type: 'post',
url: 'http://localhost:3000/search',
data: {'choices': JSON.stringify(choices)},
contentType: "application/json; charset=utf-8",
success: function (data) {
data = JSON.parse(data);
// append data to the DOM
$(".form-container").hide()
$("#status").text("and the winner is ...");
$("#decision-text").text(data['choice']);
$("#score").text('... with a score of ' + data['score'] + '');
$("#decision-text").fadeIn();
$("#score").fadeIn();
$("#again").show() },
failure: function(errMsg) {
alert("------BAD REQUEST------");
} });
// $.post('http://localhost:3000/search', {'choices': JSON.stringify(choices)}, function(data) {
// data = JSON.parse(data);
// // append data to the DOM
// $(".form-container").hide()
// $("#status").text("and the winner is ...");
// $("#decision-text").text(data['choice']);
// $("#score").text('... with a score of ' + data['score'] + '');
// $("#decision-text").fadeIn();
// $("#score").fadeIn();
// $("#again").show()
// });
//
} else {
// error code
$("#status").css("color", "red");
$("#status").text("Both choices are the same. Try again.");
}
} else {
// error code
$("#status").css("color", "red");
$("#status").text("You must enter a value for both choices.");
}
}
// ----- MAIN ----- //
// on click, run the goDecide function
$("#decision").click(goDecide);
// on click new form is shown
$("#again").click(function() {
$(".form-container").show()
$("#again").hide()
// erase old values
$("#status").text('');
$("#score").text('');
$("#choice1").val('');
$("#choice2").val('');
// hide decision text
$("#decision-text").hide();
});
});
Console output:
Failed to load resource: the server responded with a status of 400 (Bad Request)
I don't know what I am doing wrong and why my $.post
method is not working. I also tried to do the ajax method, but I don't get any result. I researched online and didn't find anything substantial that can solve my issue. I request you to please help me out. Thanks!