This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 11 months ago.
newsfeed.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>News Feed</title>
<link rel = "stylesheet" href = "stylesheets/style.css">
<script src = "javascripts/script.js"></script>
</head>
<body onload = "showNewsFeed()">
<!-- (i) -->
<div id = "header">
<input id="searchNewsHeadline" type="text">
<button onclick="">Search news headlines</button>
<a>Login</a>
</div>
<!-- (ii) -->
<div id = "news">
<!-- Display news entries -->
</div>
<!-- (iii) -->
<div id = "pageindex">
<!-- page indices -->
</div>
</body>
</html>
app.js
var express = require('express');
var app = express();
var monk = require('monk');
var db = monk('127.0.0.1:27017/assignment1');
// Make db accessible to router
app.use(function(req,res,next){
req.db = db;
next();
});
var server = app.listen(8081, function () {
var host = server.address().address;
var port = server.address().port;
console.log("Example app listening at http://%s:%s", host, port);
})
app.get('/newsfeed.html', function(req, res){
var db = req.db;
var newsList = db.get('newsList');
var response = "";
newsList.find({}, ['-_id', 'headline', 'date', 'content', '-comments']).each((news) =>{
response += "<h4>" + news['headline'] + "</h4>";
response += "<h6>" + news['date'] + "</h6>";
response += "<p>" + news['content'] + "</p>";
})
res.send(response);
});
script.js
function showNewsFeed(){
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function(){
if (xmlhttp.readyState == 4 && xmlhttp.status == 200){
var newsfeeds = JSON.parse(xmlhttp.responseText);
document.getElementById("news").innerHTML = newsfeeds;
}
}
xmlhttp.open("GET", "/newsfeed.html", true);
xmlhttp.send();
}
I am working on an assignment that fetches newsfeeds from a MongoDB database and then puts them onto the webpage (newsfeed.html). I tried to do so with these codes, it return a blank page with no output. I do believe the database is linked correctly and I am not sure which part goes wrong as no error message is kicking back.
app.get('/newsfeed.html', function(req, res){
var db = req.db;
var newsList = db.get('newsList');
var response = "";
newsList.find({}, ['-_id', 'headline', 'date', 'content', '-comments']).each((news) =>{
response += "<li><h4>" + news['headline'] + "</h4>";
response += "<h6>" + news['date'] + "</h6>";
response += "<p>" + news['content'] + "</p></li>";
}).then(()=>{
res.send(response);
})
});
Turn out it can be solved by this. I think the scope of var response makes it empty after executing the loop.
Related
This question already has answers here:
What is the difference between client-side and server-side programming?
(3 answers)
Closed 2 years ago.
i'm trying to develop a new API, but i'm meeting some problems with Javascript:
My JS/HTML CODE:
const express = require('express');
const app = express();
const PORT = 3000;
submit.onclick = function()
{
let email = document.getElementById('email').value;
let api1 = 'https://disify.com/api/email/'+email;
// Start check on API1
var xmlHttp = new XMLHttpRequest();
xmlHttp.open("GET", api1, true); // false for synchronous request
xmlHttp.onload = function()
{
if (xmlHttp.readyState === 4) //if ready
{
if (xmlHttp.status === 200) //if server response
{
console.log(xmlHttp.responseText); //write in log the response
var data = JSON.parse(this,response);
alert(data.whitelist);
var status = data.whitelist;
//var status = data.main.whitelist;
console.log(data.whitelist);
console.log(data.domain);
}
else
{
console.error(xmlHttp.statusText);
}
}
}
xmlHttp.send();
ris = document.getElementById('ris').innerHTML = "La mail: " + email + " è attualmente " +status;
};
<html>
<head>
<meta charset="utf-8">
<title>[Alpha] My Personal API v1.0</title>
<!-- <script type="text/javascript" src="server.js"></script> -->
</head>
<body>
<div style="text-align:center">
<h1>Mail Checker API - v1.0</h1>
</div>
<div style="text-align:center">
<h2>Immetti una mail:</h2>
<input type="email" id="email" name="email"></input>
<br><br>
<button id="submit">Cerca</button>
<p id="ris"></p>
</div>
<script src="server.js"></script>
</body>
</html>
As you can see, i have a button called "submit", that is linked in the javascript code by event "onclick", but the console show me this error:
First you need to define 'submit' variable then you should attach the 'click' event.
let submit = document.getElementById('submit');
submit.onclick = function()
{
};
I have a simple chat application built using sockets,MongoDB,Express.
The application works fine when hosted on my local machine (localhost:4000).
I am able to connect to MongoDB and send and receive messages.
Issue : But when I open the app on my phone browser using the PC IP address (e.g. 192.168.1.108:4000). I can see the index.html page , but unable to send and receive messages and load previous messages from mongodb.
//server.js
var express = require('express');
var app = express();
var server = require('http').createServer(app);
connections = [];
app.use(express.static(__dirname + '/public'));
server.listen(process.env.PORT || 4000);
console.log('Server Running');
app.get('/', function(req, res) {
res.sendFile(__dirname + '/index.html');
});
const mongo = require('mongodb').MongoClient;
const client = require('socket.io').listen(server).sockets;
// Connect to mongo
mongo.connect('mongodb://127.0.0.1/mongochat', function(err, db){
if(err){
throw err;
}
console.log('MongoDB connected...');
// Connect to Socket.io
client.on('connection', function(socket){
let chat = db.collection('chats');
// Create function to send status
sendStatus = function(s){
socket.emit('status', s);
}
// Get chats from mongo collection
chat.find().limit(100).sort({_id:1}).toArray(function(err, res){
if(err){
throw err;
}
// Emit the messages
socket.emit('output', res); //whenever we have to pass from server to client(index.html) , we do .emit()
});
// Handle input events
socket.on('input', function(data){
let name = data.name;
let message = data.message;
// Check for name and message
if(name == '' || message == ''){
// Send error status
sendStatus('Please enter a name and message');
} else {
// Insert message
chat.insert({name: name, message: message}, function(){
client.emit('output', [data]);
// Send status object
sendStatus({
message: 'Message sent',
clear: true
});
});
}
});
// Handle clear
socket.on('clear', function(data){
// Remove all chats from collection
chat.remove({}, function(){
// Emit cleared
socket.emit('cleared');
});
});
});
});
<!-- Index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous">
<title>MongoChat</title>
<style>
#messages{height:300px;}
</style>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-6 offset-md-3 col-sm-12">
<h1 class="text-center">
MongoChat
<button id="clear" class="btn btn-danger">Clear</button>
</h1>
<div id="status"></div>
<div id="chat">
<input type="text" id="username" class="form-control" placeholder="Enter name...">
<br>
<div class="card">
<div id="messages" class="card-block">
</div>
</div>
<br>
<textarea id="textarea" class="form-control" placeholder="Enter message..."></textarea>
</div>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.3/socket.io.js"></script>
<script>
(function(){
var element = function(id){
return document.getElementById(id);
}
// Get Elements
var status = element('status');
var messages = element('messages');
var textarea = element('textarea');
var username = element('username');
var clearBtn = element('clear');
// Set default status
var statusDefault = status.textContent;
var setStatus = function(s){
// Set status
status.textContent = s;
if(s !== statusDefault){
var delay = setTimeout(function(){
setStatus(statusDefault);
}, 4000);
}
}
// Connect to socket.io
var socket = io.connect('http://127.0.0.1:4000');
// Check for connection
if(socket !== undefined){
console.log('Connected to socket...');
// Handle Output
socket.on('output', function(data){
//console.log(data);
if(data.length){
for(var x = 0;x < data.length;x++){
// Build out message div
var message = document.createElement('div');
message.setAttribute('class', 'chat-message');
message.textContent = data[x].name+": "+data[x].message;
messages.appendChild(message);
messages.insertBefore(message, messages.firstChild);
}
}
});
// Get Status From Server
socket.on('status', function(data){
// get message status
setStatus((typeof data === 'object')? data.message : data);
// If status is clear, clear text
if(data.clear){
textarea.value = '';
}
});
// Handle Input
textarea.addEventListener('keydown', function(event){
if(event.which === 13 && event.shiftKey == false){
// Emit to server input
socket.emit('input', {
name:username.value,
message:textarea.value
});
event.preventDefault();
}
})
// Handle Chat Clear
clearBtn.addEventListener('click', function(){
socket.emit('clear');
});
// Clear Message
socket.on('cleared', function(){
messages.textContent = '';
});
}
})();
</script>
</body>
</html>
Try binding the http server on 0.0.0.0 through server.listen(process.env.PORT || 4000, '0.0.0.0') and also in your index.html you got
var socket = io.connect('http://127.0.0.1:4000');
which should actually be your internal ip.
So, the first render is successful app.get("/", function(request, response), but when I process app.post("/search", urlencodedParser, function(request, response)
I get the Error:
c:\weather\views\main.hbs: Can't set headers after they are sent.
I read that, The functionres.render()should only be called once per request., but I don't understand - How Can I change datas using views(Handlebars), if i can't call render again with new datas?
var express = require("express");
var fs = require("fs");
var bodyParser = require("body-parser");
var hbs = require("hbs");
// create object
var app = express();
//urlEncoded
var urlencodedParser = bodyParser.urlencoded({
extended: false
});
//read city.json
var content = fs.readFileSync("./city.list.json", "utf8");
var cities = JSON.parse(content);
//set view Handlebars
app.set("view engine", "hbs");
//register Helper - ResultBlock
hbs.registerHelper("ResultBlock", function(array) {
var res = "";
if (array[0] == "false") {
res = '<div class="alert alert-warning alert-dismissible fade show"><button type="button" class="close" data-dismiss="alert">×</button><strong>Not Found!</strong> The ' + array[1] + ' is not correct.</div>';
} else if (array[0] == "true") {
res = 'Succsesful!!!';
}
return new hbs.SafeString(res);
})
app.get("/", function(request, response) {
//response.sendfile('index.html');
response.render("main.hbs", {
city_value: "Zaporozhye",
data: []
})
});
app.post("/search", urlencodedParser, function(request, response) {
var city = request.body.city;
var idCity = -1;
for (let i = 0; i < cities.length; i++) {
if (cities[i].name == city) {
idCity = cities[i].id;
break;
}
}
if (idCity != -1) {
response.render("main.hbs", {
city_value: city,
data: ["true", city]
})
} else {
response.render("main.hbs", {
city_value: city,
data: ["false", city]
})
}
response.end();
});
app.listen(3000);
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="app.js" type=""></script>
<link rel="stylesheet" href="style.css">
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
<!-- jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- Popper JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script>
<!-- Latest compiled JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container-fluid" style="background-color:black; color:darkorange;">
<div class="row">
<div class="col">
<h1>Weather</h1>
</div>
<div class="col-*-*">
<form action="/search" method="post">
<div class="row">
<div class="col">
<input type="text" class="form-control" name="city" value="{{city_value}}" />
</div>
<div class="col">
<button type="submit" class="btn btn-primary">Search</button>
</div>
</div>
</form>
</div>
</div>
</div>
<div id="result_block" class="container">
{{ResultBlock data}}
</div>
</body>
</html>
response.render is an asynchronous function. So the rendering is done after the current execution context finish.
At the end of your code your call response.end() and because of that you finish the response before the rendering has started.
After you finished the response the asynchronous rendering function will start and tries to set the headers, but this is not possible because the response is already finished, and that's the reason why you get that error.
Remove the response.end() and everything should work fine.
You should delete response.end() line, since you used response.render
The function response.end() is used the send the headers of the response and ends the response process.
On the other hand, the function response.render() renders the view, and also sends the headers and ends the response.
Calling both on the same response object will try to send headers twice for the same Request, which is not possible as each request can have only one response.
So, removing the response.end() from the end of post route handler for '/search' should solve the problem.
Updated Code for '/search' POST route handler:
app.post("/search", urlencodedParser, function(request, response) {
var city = request.body.city;
var idCity = -1;
for (let i = 0; i < cities.length; i++) {
if (cities[i].name == city) {
idCity = cities[i].id;
break;
}
}
if (idCity != -1) {
response.render("main.hbs", {
city_value: city,
data: ["true", city]
})
} else {
response.render("main.hbs", {
city_value: city,
data: ["false", city]
})
}
});
We can exchange strings between our express server and a client website (even cross domain) with this code (works perfectly) :
app.js:
var express = require("express");
var app = express();
var fs=require('fs');
var stringforfirefox = 'hi buddy!'
app.get('/getJSONPResponse', function(req, res) {
res.writeHead(200, {'Content-Type': 'application/javascript'});
res.end("__parseJSONPResponse(" + JSON.stringify( stringforfirefox) + ");");
});
app.listen(8001)
index.html:
<!DOCTYPE html>
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.js"></script>
<script>
function __parseJSONPResponse(data) { alert(data); }
document.onkeypress = function keypressed(e){
if (e.keyCode == 112) {
var script = document.createElement('script');
script.src = 'http://localhost:8001/getJSONPResponse';
document.body.appendChild(script); // triggers a GET request ??????
}
}
</script>
<title></title>
</head>
<body>
</body>
</html>
We use document.createElement() and document.body.appendChild() to trigger a Get request as the highest voted answer here suggested.
Our question: is it fine to create a new Element with evey request, because we plan to make a lot of requests with this. Could that cause any problems. Or should we clear such an Element after we received the response?
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
XmlHttpRequest error: Origin null is not allowed by Access-Control-Allow-Origin
I'm developing weather application which is working fine in browsers.
But when I try to deploy in my android phone it is not working fine and it is throwing error. XML response is null. please help me.
<html>
<head>
<title>Calling Web Service from jQuery</title>
<script type="text/javascript" charset="utf-8" src="cordova-2.2.0.js"></script>
<script type='text/javascript' src='xmlObject.js'></script>
<script type='text/javascript' src='jquery-1.8.2.min.js'></script>
<script type="text/javascript" src="json2.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$("#btnCallWebService").click(function (event) {
alert('click' + $("#cityName").val());
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("POST", "http://www.webservicex.net/globalweather.asmx?op=GetWeather",true);
xmlhttp.onreadystatechange = function ()
{
if (xmlhttp.readyState == 4)
{
var myXML=xmlhttp.responseXML;
alert("Response XML in getWeatherInformation : ");
alert(myXML);
var json = XMLObjectifier.xmlToJSON(xmlhttp.responseXML);
var body=JSON.stringify(json.Body[0]);
var result = json.Body[0].GetWeatherResponse[0].GetWeatherResult[0].Text;
var myXML2=XMLObjectifier.textToXML(result);
var json2 = XMLObjectifier.xmlToJSON(myXML2);
var body2=json2;
var location=body2.Location[0].Text;
var time=body2.Time[0].Text;
var temperature=body2.Temperature[0].Text;
var pressure=body2.Pressure[0].Text;
alert("location"+location+"..."+time+".."+temperature+".."+pressure);
}
}
xmlhttp.setRequestHeader("Content-Type", "text/xml");
var xml ='<?xml version="1.0" encoding="utf-8"?>'+
'<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">'+
'<soap:Body>'+
'<GetWeather xmlns="http://www.webserviceX.NET">'+
'<CityName>'+ $("#cityName").val() +'</CityName>'+
'<CountryName>India</CountryName>'+
'</GetWeather>'+
'</soap:Body>'+
'</soap:Envelope>';
alert("Request XML : ");
alert(xml);
xmlhttp.send(xml);
});
});
function processSuccess(data, status, req, xml, xmlHttpRequest, responseXML) {
alert('success' + status + ">>" +typeof $(req.responseXML));
var myObj = new Array();
$(req.responseXML)
.find('GetWeatherResult')
.each(function(){
alert($(this));
myObj.push($(this));
});
$(myObj).each(function(){
var x = $(this).find('Location').text();
alert('loc'+ x + $(this).find('Location'));
var p = $(this).find('Location');
for (var key in p) {
alert(key + " -> " + p[key]);
}
});
}
function processError(data, status, req) {
alert(req.responseText + " " + status);
console.log(data);
console.log(status);
console.log(req);
}
</script>
</head>
<body>
<h3>
Weather Report
</h3>
Enter your city name:
<input id="cityName" type="text" />
<input id="btnCallWebService" value="GetInformation" type="button" />
</body>
</html>
You need to allow the cross domain calls to http://www.webservicex.net
See this post:
Cordova 1.9.0 Ajax not retrieving
Edit your xml in your res folder to include this line:
<access origin="http://www.webservicex.net*"/>
Or if its Phonegap-Build add that line to the config.xml