skip to Main Content

I’m having a go with the socket.io https://socket.io/get-started/chat, but my problem is that when i send message then the message cant automatically into chat box. i need to reload the page to view the chat that i sent. So how to make the chat automatically insert to chat box?. i already implement into my project. i already used socket.emit as you can see at then html file. is there the right way to put it?

server.js

var express = require('express');
var env = require('dotenv').config()
var ejs = require('ejs');
var path = require('path');
var app = express();
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
var session = require('express-session');
const MongoDBStore = require('connect-mongodb-session')(session)
const cookieParser = require('cookie-parser')

var http = require('http').Server(app);
var io = require('socket.io')(http);
var cors = require('cors')


app.use(cors())
app.use(cookieParser());

// mongodb://localhost:27017 127.0.0.1:27017
mongoose.set('strictQuery', true);
mongoose.connect('mongodb://127.0.0.1:27017/findaprofessional', {
  useNewUrlParser: true,
  useUnifiedTopology: true
}, (err) => {
  if (!err) {
    console.log('MongoDB Connection Succeeded.');
  } else {
    console.log('Error in DB connection : ' + err);
  }
});

var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function () {
});

const oneDay = 1000 * 60 * 60 * 24;
app.use(session({
  secret: 'work hard',
  saveUninitialized:true,
    cookie: { maxAge: oneDay },
    resave: true
}));

// ni lain
app.set("view engine", "ejs")

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

app.use('/css', express.static(path.resolve(__dirname, "asset/css")))
app.use('/img', express.static(path.resolve(__dirname, "asset/img")))
app.use('/js', express.static(path.resolve(__dirname, "asset/js")))
app.use('/vendor', express.static(path.resolve(__dirname, "asset/vendor")))
app.use('/lib', express.static(path.resolve(__dirname, "asset/lib")))
app.use('/scss', express.static(path.resolve(__dirname, "asset/scss")))
app.use('/pic', express.static(path.resolve(__dirname, "asset/img/pic")))



var index = require('./routes/index');
const { Socket } = require('socket.io');
app.use('/', index);

// catch 404 and forward to error handler
app.use(function (req, res, next) {
  var err = new Error('File Not Found');
  err.status = 404;
  next(err);
});

// error handler
// define as the last app.use callback
app.use(function (err, req, res, next) {
  res.status(err.status || 500);
  res.send(err.message);
});

io.on('connection', () =>{
  console.log('a user is connected')
  io.on("disconnect", function () {
    console.log("user disconnected");
  });
})


var server = http.listen(3000, () => {
  console.log('Server is started on http://127.0.0.1:'+ server.address().port);
});



routing

// user chat
var http = require('http').Server(router);
var io = require('socket.io')(http);

// Render Message
router.get('/messages/:id', async function (req, res, next) {
    user = await User.findOne({_id: req.session.userId},  {username: 1})
    return res.render("user/messages.ejs", {user: user, booking: req.params.id});
});


// Display Message from DB
router.get('/messageslist/:booking', (req, res) => {
    Message.find({booking: req.params.booking})
    .populate({
        path: "pro",
        model: Pro,
    }).populate({
        path: "user",
        model: User,
    }).exec().then((data) => {
        res.json(data)
    })
    
})


router.get('/messages', (req, res) => {
    Message.find({}, (err, messages) => {
        res.send(messages);
    })
})


router.post('/messages', async (req, res) => {
    const {booking, user, message} = req.body

    try {
        var msg = new Message({
            booking: booking,
            message: message,
            user: user
        });

        var savedMessage = await msg.save()
        console.log('saved');

        var censored = await Message.findOne({
            message: 'badword'
        });
        if (censored)
            await Message.remove({
                _id: censored.id
            })
        else
            io.emit('message', req.body);
        res.sendStatus(200);
    } catch (error) {
        res.sendStatus(500);
        return console.log('error', error);
    } finally {
        console.log('Message Posted')
    }

})

HTML

<!DOCTYPE html>
<html lang="en">


<%- include("../header.ejs") %>

<head>

  <link href="/css/sb-admin-2.min.css" rel="stylesheet">


  <link href="/css/chat.css" rel="stylesheet">

  <script src="https://code.jquery.com/jquery-3.2.1.min.js" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js"
    integrity="sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwAzpKaMNFNmj4" crossorigin="anonymous">
  </script>

  </script>
  <script src="/socket.io/socket.io.js"></script>
</head>


</head>


        <!-- start here! -->

        <section class="msger" style="margin: auto;">
          <header class="msger-header">
            <div class="msger-header-title">
              <i class="fas fa-comment-alt"></i> Chat
            </div>
            <div class="msger-header-options">
              <span><i class="fas fa-cog"></i></span>
            </div>
          </header>

          <main class="msger-chat">

          </main>

          <form class="msger-inputarea">
            <input type="hidden" name="booking" value="<%= booking %>">
            <input type="hidden" id="name" class="form-control" readonly placeholder="Name"
              value="<%= user.username %>">
            <input type="text" name="user" value="<%= user._id %>">
            <input id="message" type="text" class="msger-input" placeholder="Enter your message...">
            <button id="send" type="submit" class="msger-send-btn">Send</button>
          </form>
        </section>
        <!-- End of Main Content -->
      </div>
      <!-- End of Content Wrapper -->

    </div>
    <!-- End of Page Wrapper -->
    <!-- Scroll to Top Button-->
    <a class="scroll-to-top rounded" href="#page-top">
      <i class="fas fa-angle-up"></i>
    </a>

  </div>
  <!-- End of Main Content -->

  </div>
  <!-- End of Content Wrapper -->
  </div>
  <!-- End of Page Wrapper -->



  <!-- Bootstrap core JavaScript-->
  <script src="/vendor/jquery/jquery.min.js"></script>
  <script src="/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>

  <!-- Core plugin JavaScript-->
  <script src="/vendor/jquery-easing/jquery.easing.min.js"></script>

  <!-- Custom scripts for all pages-->
  <script src="/js/sb-admin-2.min.js"></script>

  <!-- Page level plugins -->
  <script src="/vendor/datatables/jquery.dataTables.min.js"></script>
  <script src="/vendor/datatables/dataTables.bootstrap4.min.js"></script>

  <!-- Page level custom scripts -->
  <script src="/js/demo/datatables-demo.js"></script>

  <script type="text/javascript" src="/js/mdb.min.js"></script>
  <!-- Custom scripts -->
  <script>
    var socket = io();
    $(() => {
      $("#send").click(() => {
        sendMessage({
          booking: $("input[name=booking]").val(),
          user: $("input[name=user]").val(),
          message: $("#message").val()
        });
      })
      getMessages()
    })
    socket.on('message', addMessages)
    socket.on('message', getMessages)
    socket.emit('message', getMessages)
    socket.emit('message', addMessages)

    function addMessages(message) {
      if(message.user && message.user != '') {
        if($("input[name=user]").val() == message.user._id) { 
        html = '<div class="msg right-msg"><div class="msg-img" style="background-image: url('+message.user.image +')"></div>'
        html += '<div class="msg-bubble"><div class="msg-info"><div class="msg-info-name">' + message.user.username + '</div><div class="msg-info-time">' + message.createdAt + '</div></div>'
        }
      }
       else {
        html = '<div class="msg left-msg"><div class="msg-img" style="background-image: url('+message.pro.image +')"></div>'
        html += '<div class="msg-bubble"><div class="msg-info"><div class="msg-info-name">' + message.pro.username + '</div><div class="msg-info-time">' + message.createdAt + '</div></div>'
      }
      html += '<div class="msg-text">' + message.message + '</div></div></div>'
      $(".msger-chat").append(html)

    }

    function getMessages() {

      $.get('http://localhost:3000/messageslist/<%=booking%>', (data) => {
        data.forEach(addMessages);
      })

    }

    function sendMessage(message) {
      $.post('http://localhost:3000/messages', message)
    }
  </script>



i tried to automatically get the message without reload the page but it doenst work. Can anyone see where the problem is?

2

Answers


  1. From what I know, the default behavior when you click a button with type submit inside a form, it tries to reload the page even though you haven’t defined any function or other page for it to go.

    You would have to get the submit event from the form and use the preventDefault() funciton for this event, check out this thread for more info:

    JavaScript code to stop form submission

    So you would stop the form submission and then get new messages for the page, executing the javascript to add the new messages to the page by manipulating the DOM.

    Login or Signup to reply.
  2. You can write socker.write() method for accessing real time messages in nodejs.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search