Reputation: 37
I am completely new to programming and at this stage of developing my website I need to set up a simple long polling request to get the newest messages from the db and then show them to the client. I created a messaging system last day and now it saves the messages with all needed relations between messages and users...
Here is what I did :
var express = require('express');
var router = express.Router();
var Conversation = require('../models/conversation');
var Promise = require('promise');
// Get Homepage
router.get('/', function(req, res){
res.render('index');
});
var messages = [];
router.get('/inbox', function(req, res){
var promise = new Promise(function (resolve, reject) {
req.user.conversations.forEach(function(id){
Conversation.getConversationById(id, function(err, conv){
if (conv){
messages.push(conv);
if(messages.length == req.user.conversations.length){
resolve(messages);
messages = [];
}
} else {
console.log(err);
}
});
});
}).then(function(object){
res.render('inbox', {convers: object});
}).catch(function(err){
console.log(err);
});
});
// Add new messages to messagesArray -> mesgArray to display them
var mesgArray = [];
var userIdFor = "";
router.post('/messages', function(req, res){
var convId = req.body.conversationId;
userIdFor = req.user.id;
var promise = new Promise(function(resolve, reject){
Conversation.getConversationById(convId, function(err, conver){
if (err){
console.log(err);
} else {
conver.messages.forEach(function(messa){
mesgArray.push({msg: messa.msg, owner: messa.msgOwner, ownerName: messa.msgOwnerName});
if(mesgArray.length == conver.messages.length){
resolve(mesgArray);
}
});
}
});
}).then(function(object){
res.send({allMessages: object, userId: userIdFor});
mesgArray = [];
userIdFor = "";
}).catch(function(err){
console.log(err);
});
});
// Save posted message to existent conversation
router.post('/saveMsg', function(req, res){
var conversationId = req.body.conversationId;
var messageToSave = req.body.message;
console.log(messageToSave);
console.log(conversationId);
Conversation.getConversationById(conversationId, function(err, conversation){
if (err){
console.log(err);
} else {
Conversation.getConversationById(conversationId, function(err, conversation){
if(err){
console.log(err)
} else {
conversation.messages.push({
msg: messageToSave,
msgOwner: req.user.id,
msgOwnerName: req.user.firstName
});
conversation.save(function(err){
if(err){
console.log(err);
}
})
}
});
}
});
});
module.exports = router;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.2.3/jquery.min.js"></script>
<!-- REPLAY MESSAGE BOX -->
<div class="contact-form-container hidden-mode">
<div class="row hide-contact text-right">
<img src="/images/close.png">
</div>
<form>
<div class="inbox-all-messages-container">
<div class="row inbox-all-messages">
<!-- Here will be all the messages -->
</div>
<div class="row text-center inbox-send-input">
<div class="col-lg-11 col-md-11 col-sm-11">
<textarea class="inbox-message-response-txt" placeholder="Type your message here"></textarea>
</div>
<div class="col-lg-1 col-md-1 col-sm-1 text-center inbox-message-send-btn">
<p class="inbox-message-send-msg-btn">Send</p>
</div>
</div>
</div>
</form>
</div>
<script>
$(document).ready(function(){
var convId = "";
$('.inbox-messager').on('click', function(){
$('.inbox-all-messages').empty();
var conversationId = this.getAttribute("data-conv-id");
convId = conversationId;
$.ajax({
url: '/messages',
method: 'POST',
contentType: 'application/json',
data: JSON.stringify({conversationId: conversationId}),
success: function(response){
response.allMessages.forEach(function(message){
if(message.owner == response.userId){
$('.inbox-all-messages').append(
'<div class="row inbox-message-structure-meNot">'+
'<div class="row inbox-message-header">'+
'<div class="inbox-message-ava col-lg-1 col-md-1 col-sm-1">'+
'<img src="/images/avatar.jpg" class="inbox-message-header-ava-img">'+
'</div>'+
'<div class="inbox-message-header-senderName col-lg-3 col-md-3 col-sm-3">'+
'<p>' + message.ownerName + '</p>'+
'</div>'+
'<div class="col-lg-3 col-lg-offset-5 col-md-3 col-md-offset-5 col-sm-3 col-sm-offset-5 inbox-message-header-sentTime text-right">'+
'<p>24/05/2016</p>'+
'</div>'+
'</div>'+
'<div class="row inbox-message-body">'+
'<div class="col-lg-9 col-lg-offset-1 col-md-9 col-md-offset-1 col-sm-9 col-sm-offset-1 text-left">'+
'<p>' + message.msg + '</p>'+
'</div>'+
'</div>'+
'</div>'
);
} else {
$('.inbox-all-messages').append(
'<div class="row inbox-message-structure-me">'+
'<div class="row inbox-message-header">'+
'<div class="inbox-message-ava col-lg-1 col-md-1 col-sm-1">'+
'<img src="/images/client.jpg" class="inbox-message-header-ava-img">'+
'</div>'+
'<div class="inbox-message-header-senderName col-lg-3 col-md-3 col-sm-3">'+
'<p>' + message.ownerName + '</p>'+
'</div>'+
'<div class="col-lg-3 col-lg-offset-5 col-md-3 col-md-offset-5 col-sm-3 col-sm-offset-5 inbox-message-header-sentTime text-right">'+
'<p>24/05/2016</p>'+
'</div>'+
'</div>'+
'<div class="row inbox-message-body">'+
'<div class="col-lg-9 col-lg-offset-1 col-md-9 col-md-offset-1 col-sm-9 col-sm-offset-1 text-left tester">'+
'<p>' + message.msg + '</p>'+
'</div>'+
'</div>'+
'</div>'
);
}
});
$('.inbox-all-messages').append('<div id="bottom"></div>');
$('.inbox-all-messages').scrollTo('#bottom', 100, "max");
}
});
$('.contact-form-container').removeClass('hidden-mode');
$('.messenger-contaner').addClass('stop-scroll');
});
$('.hide-contact').on('click', function(){
$('.contact-form-container').addClass('hidden-mode');
$('.messenger-contaner').removeClass('stop-scroll');
});
$('.inbox-message-send-msg-btn').on('click', function(){
var messageToSend = $('.inbox-message-response-txt').val();
$.ajax({
url: '/saveMsg',
method: 'POST',
contentType: 'application/json',
data: JSON.stringify({message: messageToSend, conversationId: convId}),
success: function(response){
alert('le message a bien ete enregistree');
}
});
});
})
</script>
Now I can send messages and store them in my mongoDB but I need to refresh the page to get the new messages... So I am trying to set up a long polling request but can't find a solution because each time I set a loop in my jQuery code it breaks the whole page and it can't open a conversation no more... If someone can help me to improve my code and set up a simple no technology to get the message without refreshing the page it would be so wonderful!
Sorry for my bad English! And thank you a lot for geing there for us!
Upvotes: 1
Views: 577
Reputation: 111258
If you are completely new to programming as you said, then instead of trying to create the functionality from scratch that you have trouble with, maybe using a working solution would be a better idea.
You can use Socket.io for that sort of thing. It uses long polling and tries to upgrade to WebSocket if it's supported. It's very simple to use. Here is an entire working example of a server that sends requests to the client:
var path = require('path');
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, 'si.html'));
});
io.on('connection', s => {
for (var t = 0; t < 3; t++)
setTimeout(() => s.emit('message', 'message from server'), 1000*t);
});
http.listen(3002, () => console.error('listening on http://localhost:3002/'));
And here is the entire JavaScript code on the client:
var l = document.getElementById('l');
var log = function (m) {
var i = document.createElement('li');
i.innerText = new Date().toISOString()+' '+m;
l.appendChild(i);
}
log('opening socket.io connection');
var s = io();
s.on('connect_error', function (m) { log("error"); });
s.on('connect', function (m) { log("socket.io connection open"); });
s.on('message', function (m) { log(m); });
For more examples and better explanation see the project on GitHub which I created to demonstrate the usage of sending messages to the client.
See also other related questions for more details:
Upvotes: 2