socket.io emit not working properly inside express route - angularjs

I use soket.io in Node.js it's working fine, but there is an issue in the routes files.
Below is my code and flow.
I have server.js file where I define io.
var express = require('express'),
app = express(),
http = require('http').Server(app);
var io = require('socket.io').listen(http);
//io from server.js
io.on('connection', function (socket) {
socket.emit('getDevicePostData', { message : 'Hi from server!!' });
socket.on('sendDevicePostData', function("Hi from server") {});
});
// pass io to routes file
var smart_control = require('./smart_control.js')(io);
app.use('/', smart_control);
And smart_control.js file code is below
module.exports = function(io) {
router.post('/emitdata', function(req, res, next) {
io.sockets.emit('getDevicePostData', { message : 'Hi from route!!' });
});
return router;
}
Above route's emit sometimes work and sometimes does not work.
And this emit is called from angular js. I use https://www.npmjs.com/package/angular-socket-io package in angular
Below code in angular controller:
mySocket.on('getDevicePostData', function(data) {
console.log(data);
});
Here mySocket is factory.
What is wrong in my code. Mainly problem from routes file only.

You just need to replace io.sockets.emit with io.emit.
Here io.sockets.emit will emit to only connected clients and your socket factory might not be up by the time you hit the API.

Related

Redirect to ''/'' in Node.js + AngularJS

I created a project on Node.js + AngularJS I have routes in this project. How I can create redirect to '/' if the user prints whatever link in searching panel.
i would recommend to use ExpressJS as nodeJS framework but via nodeJS you can use the router library to acheive the same.
var finalhandler = require('finalhandler')
var http = require('http')
var Router = require('router')
var router = Router();
//other route urls here
//have this at the end
router.get('/*', function (req, res) {
res.setHeader('Content-Type', 'text/plain; charset=utf-8')
res.end('Hello World!');
//or write you logic here.
})
var server = http.createServer(function(req, res) {
router(req, res, finalhandler(req, res))
})
server.listen(3000)
Read in detail about the Router Library
Also read here

Post SQL data to Angular View with NodeJS

I'm having a difficult time posting data retrieved from a server using mysql with node. I have connected to my db successfully, and I can return the data I want by console logging it to the CLI when running "node server.js". However, I'm not sure how to post this data to my Angular view. No problem console logging, but this doesn't help me get data to the application.
For the moment, I'm just trying to get the data to index.html, which is my primary view and holds my ng-view portion for Angular routing. I'm probably missing something obvious bc I'm new to NodeJS.
// MODULES
var express = require('express');
var app = express();
var port = process.env.PORT || 3000;
var mysql = require('mysql');
var serveStatic = require('serve-static');
var bodyParser = require('body-parser');
var source = __dirname + '/public/views/index.html';
app.use(serveStatic(__dirname, {'index': ['index.html']}));
app.route('/*')
.get(function(req, res) {
res.sendFile(source);
});
var data;
var connection = mysql.createConnection({
host : 'thehostdb',
user : 'username', // credentials correct, connection works
password : 'pw',
database : 'db',
port: '3306'
});
connection.query('SELECT * from poemTable', function(err, rows, fields) {
if (!err) {
data = JSON.stringify(rows);
setDataValue(data);
}
else {
console.log('Error while performing Query:', err);
}
});
function setDataValue(value) {
data = value;
console.log(data); //Where the data logs
}
app.listen(port, function () {
console.log('Example app listening on port' + port + '!')
})
You have to understand what this code does, and how nodejs and angular are supposed to work together. Angular is served to the client and then rendered by the clients browser. So if you want to inject data you have to fetch it. So in your angular app when the controller starts make an api call, and in your server create a new route:
app.get('/data', function(req, res, next) {
connection.query(..., function(err, rows, fields) {
res.json(rows);
});
});
Make sure you understand node and it's async nature, what is event loop and how it works and what is callback hell, also I would check out promises and other tutorials on nodeschool.io, it's a great place to start with node :)

How to retrieve response from server using angularjs?

I am sending filename to server and trying to get some sort of response to make sure api calls are working but its always returing 404 even though path is correct, I am not sure where i am making mistake , Any idea ?
angularjsFactory.js
getFile:function(file_name){
return $http.get("/file?file_name="+file_name);
}
server.js
var express = require('express');
var app = express();
var fs = require('fs');
app.use(express.static(__dirname + "/public"));
var readDirectory = require('./readDirectory');
app.get('/file', function(req, res) {
var path = './ditLogs';
var fileParam = req.query.file_name;
console.log(fileParam);
fs.readdir(path, function(err, items) {
items.forEach(function(items) {
if (fileParam === items) {
res.sendFile(items);
console.log(items);
}
});
});
});
app.listen(3000, function() {
console.log('Example app listening on port 3000!');
//console.log('app is printing data',obj);
//ditProducer.startProducer();
setTimeout(function() {
ditconsumer.start();
}, 2000);
});
Your route on server is not correct comparing to the call from angular's side. You are not using route parameters, but query string.
Try this:
app.get('/file', function (req, res) {
// get filename using: req.query.file_name
res.send('FIle data');
});
Or you can try this on angular and keep the server code:
$http.get("/file/"+ encodeURI(file_name));
Server side code looks incorrect.
app.get('/file', function (req, res) {
console.log(req.query.file_name);//This will give you filename passed as url param
res.send('FIle data');
});

How to create RestFull api with express and node.js?

I am very new to node and express i read some documentation but i did not get any solid understanding how to create rest api with node, So with below basic code i just want to create get api with express and return response to angularjs factory method.I would like to get help and better understanding for the following .
1- How to return response with GET api ?
2- If we have json object how can i pass that data using GET api ?
app.js
var express = require('express');
var path = require('path');
var app = express();
app.use(express.static('./'));
var server = app.listen(3000, function(){
var host = server.address().address;
var port = server.address().port;
console.log('Example app listening at http',host,port);
});
app.get('/test', function(req, res) {
res.type('text/plain'); // set content-type
res.send('i am a beautiful butterfly'); // send text response
});
workerController.js
$scope.getTestData = function(){
alert('got function working');
workerFactory.getData().then(function(response){
var dataResponse = response.data;
console.log(dataResponse);
})
}
workerFactory.js
angular.module('myApp').factory('workerFactory', function ($http) {
'use strict';
return {
getData: function(){
return $http.get('/test');
}
}
});
For the second part, how to pass a JSON object back. You can change your API code to something like:
app.get('/test', function(req, res) {
res.json({message: 'i am a beautiful butterfly'}); // send a JSON response
});
I'm just working on the first part of the question
You can get a full working REST-full API code by using Amplication, it's an open-source for generating Node.js code by only defining your data model.
As you have the basic understanding on REST API you can use this node module
https://github.com/swagger-api/swagger-node for creating great REST API.

In Express.js with body-parser the value of request.body is undefined

I'm having a problem I cannot diagnose.
On a server, I have a simple URL handler using Express.js:
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var multer = require('multer');
app.configure(function() {
app.use(app.router);
app.use(bodyParser.json()); // see: http://expressjs.com/api.html#req.body
app.use(bodyParser.urlencoded({
extended: true
}));
});
app.post('/submit', function (req, res) {
console.log(req.body);
});
On client side, there's a form which is handled with Angular controller:
$scope.submit = function () {
// $http.post('/submit', $scope.data); // POST request to send data to the server
$http({
method: 'POST',
url: '/submit',
data: $scope.data
});
console.log('POST /submit ' + JSON.stringify($scope.data));
};
In browser's console everything is fine: $scope.data is valid; Node.js also responds with console.log, as expected, but writes undefined which means that, well, request.body is undefined.
What do I do wrong? How can I fix it?
If you're using Express 3 you shouldn't have to use the body-parser module as it is already bundled with Express 3 as express.bodyParser. You're getting an empty body because you're putting app.use(app.router) before the body parser.
app.configure(function() {
app.use(express.bodyParser());
app.use(app.router);
});
Which is why your other solution is working:
app.post('/submit', bodyParser.json(), function (req, res) {
Well, I just came up with solution, and it works. Here the app.post using body-parser is explained in few words. So I changed POST request handler definition to:
app.post('/submit', bodyParser.json(), function (req, res) {
console.log(req.body);
});
And now not only console.log(req.body) returns valid data, but it's deserialized into JSON correctly on the server without any extra code (which is, well, expected from Angular+Node pair).

Resources