Node server to echo POST/URL parameters in real time - ajax

I'm working on a project where I'm sending temperature data via Arduino to a Node server. Arduino sends data to the server through URL parameters:
http://localhost:3000/submit?temprature=25
I'm then fetching the posted data using the following Node server.js
var express = require('express');
url = require('url');
var app = express();
app.get('/submit', function(req, res){
var data = url.parse(req.url,true).query;
console.log(data);
});
app.listen(3000, function(){
console.log('listening on *:3000');
});
I'm able to show the required data with console.log(), but what I want is, as soon as Arduino sends the data through URL parameters, that data should automatically echo/print on the server: http://localhost:3000/index.html like in real time. How can I achieve this?

You can use socket.io to emit events every time the temperature is updated by your arduino device:
var http = require('http');
var url = require('url');
var express = require('express');
var app = express();
var server = http.createServer(app);
var io = require('socket.io').listen(server); //pass a http.Server instance
server.listen(3000);
app.get('/submit', function(req, res){
var data = url.parse(req.url,true).query;
io.emit('temperature', data);
res.send('Temperature Updated to: ' + data.temperature);
});
app.get('/index', function(req, res){
res.sendFile(__dirname + '/public/index.html');
});
Then on the client side, you can listen for events and update the information. This is public/index.html:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Socket.IO Temperature Example</title>
<link rel="stylesheet" href="style.css">
<script src="https://cdn.socket.io/socket.io-1.3.5.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-alpha1/jquery.min.js"></script>
</head>
<body>
<h1 id="temperature"></h1>
<script>
var socket = io('http://localhost:3000');
socket.on('temperature', function (data) {
console.log(data);
$('h1#temperature').html(data.temperature);
});
</script>
</body>
</html>

Related

function won`t run in if statement (eventlistener && eventlistener) javascript

I'm trying to get an if statement going to get api results.
First I put eventlisteners(click) on my images and when they are BOTH clicked, the get-api-results function should run.
I know I asked something similar before but I got that one screwed up, with this I`m a little closer I think.
Here`s the code
import axios from 'axios';
const container = document.getElementById('container')
let img = document.createElement("img");
img.src = "https://picsum.photos/200/301";
let img2 = document.createElement("img2");
img2.src = "https://picsum.photos/200/300";
const imgCheck = img.addEventListener("click", function(e) {
console.log("check")
})
const img2Check = img2.addEventListener("click", function(e) {
console.log("ok")
})
img.onclick = function () {location.href = "http://localhost:1234/pageTwo.html";};
document.body.appendChild(img);
document.body.appendChild(img2);
if (imgCheck && img2Check){
async function fetchRecipeOne() {
try {
const result = await axios.get('https://api.spoonacular.com/recipes/complexSearch?query=pasta&maxFat=25&number=2&apiKey=0b4d29adff5f4b41908e8ef51329fc48', {
headers: {
"Content-Type": "application/json"
}
})
console.log(result);
} catch (e) {
console.error(e);
}}
fetchRecipeOne();
} else {
console.log('no results');
}
And the html pages
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="styles.css">
<title>Title</title>
</head>
<body>
<img ><img/>
<script type="module" src="app.js"></script>
</body>
</html>
And page 2:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="styles.css">
<title>Title</title>
</head>
<body>
<img id="img2"><img/>
<script type="module" src="app.js"></script>
</body>
</html>
Again, I`m pretty new to this stuff so if can give me enough details to sort this out you would do me a big favour.
Thanks!
Tom
addEventListener() does not return anything.
Maybe you can create a variable and change it in the eventlistener, like so:
let imgCheck = false;
img.addEventListener("click", function(e) {
imgCheck = true;
});
let img2Check = false;
img2.addEventListener("click", function(e) {
img2Check = true;
});
Also you redirect the user when he click on img, reset the click so to say. Maybe delete that
And the where you define img2 you try to create an element with the name 'img2' which isn't a valid element.
So change:
let img2 = document.createElement("img2");
To:
let img2 = document.createElement("img");
Lastly you check is the user has clicked on both the images when the script runs, what you can do is set the if statement in the async function, and call the function when the user clicks on a img.
So it could look something like:
import axios from 'axios';
const container = document.getElementById('container')
let img = document.createElement("img");
img.src = "https://picsum.photos/200/301";
let img2 = document.createElement("img");
img2.src = "https://picsum.photos/200/300";
let imgCheck = false;
img.addEventListener("click", function(e) {
imgCheck = true;
fetchRecipeOne();
});
let img2Check = false;
img2.addEventListener("click", function(e) {
img2Check = true;
fetchRecipeOne();
});
document.body.appendChild(img);
document.body.appendChild(img2);
async function fetchRecipeOne() {
if (imgCheck && img2Check) {
try {
const result = await axios.get('https://api.spoonacular.com/recipes/complexSearch? query=pasta&maxFat=25&number=2&apiKey=0b4d29adff5f4b41908e8ef51329fc48', {
headers: {
"Content-Type": "application/json"
}
})
console.log(result);
} catch (e) {
console.error(e);
}
} else {
console.log('no results');
}
}

Why does 'import socket.io' doesn't work for me?

I'm learning Socket.io and practicing the demo tutorial with individual client side script file.
However, it didn't work as expected.
Here is my code.
client side HTML: index.html
<!DOCTYPE html>
<html>
<head>
...
</head>
<body>
<ul id="messages"></ul>
<form id="form" action="">
<input id="input" autocomplete="off" /><button>Send</button>
</form>
<script src="./app.js"></script>
</body>
</html>
client side JS: app.js
import { io } from "socket.io-client";
var socket = io('http://localhost:3000');
var messages = document.getElementById('messages');
var form = document.getElementById('form');
var input = document.getElementById('input');
form.addEventListener('submit', function(e) {
e.preventDefault();
if (input.value) {
socket.emit('chat message', input.value);
input.value = '';
}
});
socket.on('chat message', function(msg) {
var item = document.createElement('li');
item.textContent = msg;
messages.appendChild(item);
window.scrollTo(0, document.body.scrollHeight);
});
server side JS: index.js
const app = require('express')();
const http = require('http').Server(app);
const io = require('socket.io')(http);
const port = process.env.PORT || 3000;
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html');
});
io.on('connection', (socket) => {
console.log('a new user join: ', socket.id);
socket.on('chat message', msg => {
io.emit('chat message', msg);
});
});
http.listen(port, () => {
console.log(`Socket.IO server running at http://localhost:${port}/`);
});
After node index to execute my server and open localhost:3000 on my browser, the console.log should tells 'a new user join: xxx', but it didn't.
Is there anything wrong with client side app.js?

complex nodejs url mapping

I need help in url mapping in express.js framework in nodejs.
router.get('/first/:second_param', function(res,req){
//processing second_param and rendering a template,
res.render('first.html');
});
router.get('/first/:second_param/get_items', function(res,req){
//again evaluating second_param and and responding accordingly
res.send(jsonData);
});
Is this kind of routing possible in Express 4.0?
first.html makes a ajax request at url './get_items'
Yes, it is possible to do it with Express 4.0.
Here is an example:
you need to install ejs and express: npm install ejs express
app.js file:
var express = require('express');
var app = express();
app.set('view engine', 'ejs');
app.get('/', function(req, res) {
res.redirect('/home/2');
});
app.get('/home/:itemId', function(req, res) {
var itemId = req.params.itemId;
console.log(itemId);
res.render('index');
});
app.get('/api/items/:itemId', function(req, res) {
var itemId = req.params.itemId;
console.log('item id: %s', itemId);
res.json([{name: 'item1'}]);
});
app.listen(8080, function() {
console.log('server up and running at 8080');
});
views/index.ejs file:
<!doctype html>
<html>
<head>
</head>
<body>
<h1>Hello World!</h1>
<script>
function responseGET() {
if(this.readyState !== 4 || this.status !== 200) return;
alert(this.responseText);
}
function getItems(URL) {
var request = new XMLHttpRequest();
request.open('GET', URL, true);
request.onreadystatechange = responseGET.bind(request);
request.send(null);
}
function domReady() {
getItems('http://localhost:8080/api/items/1');
}
document.addEventListener('DOMContentLoaded', domReady);
</script>
</body>
</html>
Basically I am have a server which is serving an index.html when someone requests at /home/:itemId and also I am exposing another route for serving items /api/items/:itemId.
From the client side once the DOM is ready I am requesting to /api/items/:itemId some items which then are displayed in the index html.

node.js ajax express show restful data on a web page

I am newbie in node.js development and I have a particular problem. I want to create a one page web app with node.js which will the user will submit request data and then gets data back from imdb api and will show them on the same page. My code is the following
server.js
#!/usr/bin/env node
var express = require('express');
var app = express();
app.configure(function(){
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(__dirname + '/public'));
});
var fs = require('fs');
var inputFile = fs.readFileSync('index.html').toString();
console.log(inputFile);
app.get('/', function(request, response) {
response.send(inputFile);
});
var port = process.env.PORT || 8080;
app.listen(port, function() {
console.log("Listening on " + port);
})
app.post('/', function(req, res){
if (req.body.mysearch == ""){
var search = "heroes";
}else{
var search = req.body.mysearch;
}
console.log(search);
var http = require('http');
http.get("http://www.imdbapi.com/?t=" + search, function(res) {
console.log("Got response: " + res.statusCode);
var data = '';
res.on('data', function (chunk){
data += chunk;
})
res.on('end',function(){
// the whole of webpage data has been collected. parsing time!
var obj = JSON.parse(data);
console.log( obj.Title );
})
}).on('error', function(e) {
console.log("Got error: " + e.message);
})
});
index.html
<html>
<head>
<meta charset="utf-8">
<title>Title of the document</title>
</head>
<body>
<form id="myform" method="post" action="/"enctype="application/x-www-form-urlencoded">
<input type="text" id="search" name="mysearch">
<input type="submit" id="mysubmit" value="Search IMDB">
</form>
<div id="myTitle">
</div>
</body>
</html>
The code so far has successfully parsing the data from imdb and shows them on the console. The question is how I am going to print them on the web page (e.g on the div tag) without reload the page (ajax)
I had a similar question regarding re-rendering of div that got answered
how-to-re-render-html-div-in-node-js
Basically solution was to use client side frameworks like Angular.js to help in re-rendering via 2 way data binding.

How can i optimize/speed up the response time of Ajax

<script type="text/javascript">
function insert_comment(id)
{
var comment_des = $("#comment_text_"+id).val();
var fk_post_id = $("#fk_post_id_"+id).val();
var post_user_id = $("#post_user_id_"+id).val();
var user_id = $("#user_id_"+id).val();
$.post('ajax_files/insert_comment.php',
{comment_des:comment_des,user_id:user_id,fk_post_id:fk_post_id,post_user_id:post_user_id},
function(data)
{
$("#ajaxdata").html(data);
});
}
</script>
Send less data to begin with maybe gzip it.
But AJAX isn't designed to be realtime. if you want realtime you should move to websockets.

Resources