Node.js http.createServer throws TypeError: listener must be a function - koa

index.js:
var koa = require('koa')
, Primus = require('primus.io')
, http = require('http')
, app = koa()
, server = http.createServer(app);
var primus = new Primus(server, { transformer: 'websockets', parser: 'JSON' });
primus.on('connection', function (spark) {
spark.send('news', { hello: 'world' });
spark.on('my other event', function (data) {
console.log(data);
});
});
app.get('/', function (req, res) {
res.sendfile(__dirname + '/index.html');
});
server.listen(8080);
console.log('8080');
run: node --harmony index
and err: throw TypeError('listener must be a function');

You need to change your code to do this:
server = http.createServer(app.callback())

Try: add a star '*'
app.get('/',function*(next){})

Related

SocketIO 4 - won't emit to the room

I have following server code:
const path = require("path");
const http = require("http");
const express = require("express");
const {instrument} = require('#socket.io/admin-ui')
const {jwtDecode, jwtVerify, resignJwt} = require('jwt-js-decode')
const secret =
"xxxxxxx";
const app = express()
const server = http.createServer(app)
const io = require("socket.io")(server, {
cors: {
origin: ["https://admin.socket.io", "http://localhost:3001"],
credentials: true
},
});
let servantID = ''
io.use((socket, next) => {
const header = socket.handshake.headers["authorization"];
jwtVerify(header, secret).then((res) => {
if (res === true)
{
const jwt = jwtDecode(header);
servantID = jwt.payload.iss;
return next()
}
return next(new Error("authentication error"));
});
});
instrument(io, { auth: false });
server.listen(3000, () =>
console.log('connected')
)
io.on('connection', socket => {
socket.on("join", (room, cb) => {
console.log('Joined ' + room);
socket.join(room);
cb(`Joined the best room ${room}`)
});
socket.on('newOrder', function (data) {
socket.to('servant').emit('this', data);
console.log(data);
})
socket.on("thisNew", function (data) {
console.log('this new');
});
socket.on('disconnect', () => {
console.log('user disconnected');
});
})
And client side code:
socket.emit('join', 'servant', message => {
console.log(message)
})
socket.on('this', () => {
console.log('this event')
})
socket.emit('newOrder', 'data')
When I emit like this:
socket.to('servant').emit('this', data);
the client doesn't receive anything, but if I emit without room:
socket.emit('this', data);
the event and data are received on the client side.
What am I doing wrong here?

Display image on pug

I'm new to NodeJS world.
I tried to display image from mongodb using pug and node express.
Please see my code and guide me.
customer.pug
extend layouts
block content
h1.container #{title} of #{customer.full_name}
div.container
p Full Name: #{customer.full_name}
p Address: #{customer.address}
p Age: #{customer.age}
img.imageScr1(src=customer.profileimage, alt=customer.full_name)
app.js
const express = require('express');
const path = require('path');
const router = express.Router();
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const fs = require('fs');
const multer = require('multer');
// set storage engine
const storage = multer.diskStorage({
destination: function(req, file, cb){
cb(null, './uploads/',)
},
filename: function (req, file, cb) {
cb(null, file.fieldname + Date.now() + path.extname(file.originalname));
}
});
// init upload
const upload = multer({
storage: storage
});
// Middlewares
// middleware for Assets - to set public for assets
app.use(express.static(path.join(__dirname, 'public')));
app.use('/uploads', express.static(path.join(__dirname, 'uploads')));
// route - homepage
app.get('/', function (req, res) {
Customer.find({}, null, function(err, customers) {
if(err){
console.log(err);
} else{
// customers.profileimage = '/' + customers.profileimage;
// console.log('image prefix::: ' + customer.profileimage);
res.render('index', {
title: 'Customer List',
customers: customers
});
}
});
});
app.post('/customer/add', upload.single('profileimage'), function (req, res) {
var customer = new Customer();
customer.full_name = req.body.full_name;
customer.address = req.body.address;
customer.age = req.body.age;
customer.profileimage = req.file.path;
customer.save(function (err) {
if(err){
console.log(err);
} else{
res.redirect('/');
}
});
});
I got following error when render customer.pug view.
error_console
I found that, if I add '\' before image path 'uploads\profileimage1520473825415.jpg', it displays image.
I tried many ways to do that did not work.
Please help me.
Cheers

Cannot POST ajax request

can anyone explain to me why i cannot post the ajax request. When i run this code the console appear POST http://localhost:8080/api/users 404 (Not Found), and in the networth part the preview is 404 not found
In the index.js file
var path = require('path');
var express = require('express');
var webpack = require('webpack');
var config = require('./webpack.config.dev.js');
var app = express();
var compiler = webpack(config);
var bodyParser = require('body-parser');
var users = require('./server/routes/users');
app.use(bodyParser.json());
app.use('/api/users', users);
app.use(require('webpack-dev-middleware')(compiler, {
noInfo: true,
publicPath: config.output.publicPath
}));
app.use(require('webpack-hot-middleware')(compiler));
app.get('*', function(req, res) {
res.sendFile(path.join(__dirname, 'index.html'));
});
app.listen(8080, 'localhost', function(err) {
if (err) {
console.log(err);
return;
}
console.log('Listening at http://localhost:8080');
});
and the users file
var express = require('express')
var router = express.Router()
// middleware that is specific to this router
function validateInput(data) {
let errors = {};
if (Validator.isNull(data.username)){
errors.username = "This field is required";
}
if (Validator.isEmail(data.email)) {
errors.email = "Email is invalid";
}
if (Validator.isNull(data.password)){
errors.password = 'This field is required';
}
if (Validator.isNull(data.passwordConfirmation)){
errors.passwordConfirmation = 'This field is required';
}
if (Validator.equals(data.password, data.passwordConfirmation)){
errors.passwordConfirmation = 'Password must match';
}
return {
errors,
isValid: isEmpty(errors)
}
}
router.post('/api/users', (req, res) => {
console.log('runiing the router/post');
console.log(req.body);
const {errors, isValid} = validateInput(req.body);
if (!isValid) {
res.status(400).json(errors);
}
});
module.exports = router
in users.js file the function should be
router.post('/', (req, res) => {
console.log('runiing the router/post');
console.log(req.body);
const {errors, isValid} = validateInput(req.body);
if (!isValid) {
res.status(400).json(errors);
}
});
Because index.js have already resolved /api/users part in the request url http://localhost:8080/api/users at this point. So you only have to map after the /api/users in your users js file.
For example, if you have following function in users.js file
router.post('/:id', (req, res) => {
...
}
It will resole to the path http://localhost:8080/api/users/1
Edit
In your existing version,
router.post('/api/users', (req, res) => {
...
}
will resolve as http://localhost:8080/api/users/api/users

Simple bluebird example with restify doesn't work

taking straight from this post:
This code never executes.
var Promise = require("bluebird");
Promise.promisifyAll(require("restify"));
var restify = require("restify");
var http = require('http');
const PORT=7070;
function handleRequest(request, response){
response.end('It Works!! Path Hit: ' + request.url);
}
var server = http.createServer(handleRequest);
server.listen(PORT, function(){
console.log("Server listening on: http://localhost:%s", PORT);
});
var client = restify.createJsonClientAsync({
url: 'http://127.0.0.1:7070'
});
client.get("/foo").spread(function(req, res, obj) {
console.log(obj);
});
I only put together this simple example to prove it to myself after my production code didn't work. I can hit localhost:7070 with curl and I get the expected results.
In a nutshell: I need to execute 3 GET calls to a server before I can create a POST and hence my need for promises.
Anyone can shed some insight? I can't imagine this being simpler.
UPDATE
Apparently i did not read the question correctly, here is a working example of 2 gets using a promisified restify json client. you would just do another spread in the body of the second spread for your post.
var promise = require('bluebird');
var restify = require('restify');
promise.promisifyAll(restify.JsonClient.prototype);
var client = restify.createJsonClient({
url: 'http://localhost:8080',
version: '*'
});
client.getAsync('/api/resource/1').spread(function(req, res, obj) {
console.log('result 1', obj);
return client.getAsync('/api/resource/2').spread(function(req, res, obj) {
console.log('result 2', obj);
});
});
As I stated in my comments, I would not promisify restify itself. Instead I would use either a handler whose body executes promise code or a chain of handlers (which can also have promises in the body). restify should only receive the request and execute the handler.
I will use modified versions of the basic example from the restify page to illustrate each.
Promise in the message body using knex.js which returns a promise
var knex = require('knex')(connectionConfig);
var restify = require('restify');
function promisePost(req, res, next) {
// get 1
knex.select('*')
.from('table1')
.where('id', '=', req.body.table1_id)
.then(function(result1) {
// get 2
return knex.select('*')
.from('table2')
.where('id', '=', req.body.table2_id)
.then(function(result2) {
return knex('table3').insert({
table1_value: result1.value,
table2_value: result2.value
})
.then(function(result3) {
res.send(result3);
return next();
});
});
});
}
var server = restify.createServer();
server.use(restify.bodyParser());
server.post('/myroute', promisePost);
server.listen(8080, function() {
console.log('%s listening at %s', server.name, server.url);
});
now with chained handlers
var knex = require('knex')(connectionConfig);
var restify = require('restify');
function get1(req, res, next) {
knex.select('*').from('table1')
.where('id', '=', req.body.table1_id)
.then(function(result1) {
res.locals.result1 = result1;
return next();
});
}
function get2(req, res, next) {
knex.select('*').from('table2')
.where('id', '=', req.body.table2_id)
.then(function(result2) {
res.locals.result2 = result2;
return next();
});
}
function post(req, res, next) {
knex('table3').insert({
table1_value: res.locals.result1,
table2_value: res.locals.result2
})
.then(function(result3) {
res.send(result3);
return next();
});
}
var server = restify.createServer();
server.use(restify.bodyParser());
server.post('/myroute', get1, get2, post);
server.listen(8080, function() {
console.log('%s listening at %s', server.name, server.url);
});

Why isn't the server sending or the client receiving data via socket.io in my express app?

My node app posts an object (consisting of data collected in a form on the client) to Salesforce via their API. On receiving a success or error message, I would like to send it to the client-side, then display it. Socket.io seemed like the tool for this in my simple node/express3 app, but beyond the simple demo I'm not able to get data to pass between my server and my client.
My relevant server side code:
var express = require('express');
var port = 5432;
var app = module.exports = express();
var server = require('http').createServer(app);
var nforce = require('nforce');
var org = nforce.createConnection({
clientId: 'MY_CLIENT_ID',
clientSecret: 'MY_CLIENT_SECRET',
redirectUri: 'http://localhost:5432/oauth/_callback'
});
var io = require('socket.io').listen(server);
// here I authenticate with Salesforce, this works fine
app.post('/salesforce', function(req, res){
var lead = nforce.createSObject('Lead');
// here I construct the lead object, which also works fine
org.insert(lead, oauth, function(err, res) {
if (err === null) {
console.log(res);
leadSuccessMessage(res);
}
else {
console.log(err);
var error = {
errorCode: err.errorCode,
statusCode: err.statusCode,
messageBody: err.messageBody
};
console.log(error);
leadErrorMessage(error);
}
});
}
function leadSuccessMessage(res) {
var resp = res;
console.log('called success message from server');
io.sockets.on('connection', function (socket) {
socket.emit('sfRes', resp);
socket.on('thanks', function (data) {
console.log(data);
});
});
}
function leadErrorMessage(error) {
var err = error;
console.log('called error message from server');
io.sockets.on('connection', function (socket) {
console.log("socket is: " + socket);
socket.emit('sfRes', err);
socket.on('thanks', function (data) {
console.log(data);
});
});
}
And my relevant client side scripts:
<script src="/socket.io/socket.io.js"></script>
<script>
current.page = document.URL;
console.log("current page is: " + current.page);
var socket = io.connect(current.page);
socket.on('sfRes', function (data) {
console.log("client received: " + data);
fst.showLeadStatus(data);
socket.emit('thanks', {message: "received server feedback"});
});
</script>
When I post the form containing valid data using a spicy little AJAX call:
postToSF: function(){
$('#submitLead').on('click', function(e){
e.preventDefault();
var formData = $('#lead_form').serialize();
$.ajax({
type: 'POST',
url: '/salesforce',
data: formData,
success: function(){
fst.log('success!');
},
error: function(xhr, ajaxOptions, thrownError){
console.error(xhr.status); // 0
console.error(thrownError);
}
});
});
}
All I get are tears, and these in the server-side console:
// the result of `console.log(res)`
{ id: '00Qa000001FZfhKEAT', success: true, errors: [] }
// and proof that `leadSuccessMessage()` got called
called success message from server
Instead of calling this function from a client-side object as it's supposed to:
showLeadStatus: function(response){
if (response.success) {
fst.log("showing lead status as: " + response);
$('#leadStatus').addClass('success').removeClass('error').fadeIn().delay(4000).fadeOut();
}
else {
fst.log("showing lead status as: " + response);
$('#leadStatus').text(response.messageBody).addClass('error').removeClass('success').fadeIn().delay('4000').fadeOut();
}
$('#startOver').click();
}
Which works fine if I call it in the console passing it the data the server is supposed to be socketing over:
// this works, gosh darn it
fst.showLeadStatus({ id: '00Qa000001FZfhKEAT', success: true, errors: [] });
The Salesforce post error case doesn't surface anything to the client either. And there are no errors in the client or server console to contend with.
I'm stumped. Please help!
I would do something like this -
var mysocket = null;
var io = require('socket.io').listen(server);
io.sockets.on('connection', function (socket) {
mysocket = socket;
socket.on('thanks', function (data) {
console.log(data);
});
});
app.post('/salesforce', function(req, res){
....
....
})
function leadSuccessMessage(res) {
var resp = res;
console.log('called success message from server');
if(mysocket)
mysocket.emit('sfRes', resp);
}
function leadErrorMessage(error) {
var err = error;
console.log('called error message from server');
if(mysocket)
mysocket.emit('sfRes', err);
}

Resources