Advertisement

Another Node.js / JavaScript question

Started by November 28, 2018 08:16 AM
4 comments, last by Bregma 6 years ago

Slowly working through the tutorial on Node.js - And found another thing that does my head in -.really want to understand what is happening. It's a very simple chat client/server in Express+node.js.

When I run my code, this is the browser output:mycodeoutput.jpg.e4171f7147fb3886db966dc4441a4703.jpg

But, when I run the tutorial code, I get this (which is what I think my code should produce as well:

tutcodeoutput.thumb.jpg.9310a502e052ec3fb63e2f142b849362.jpg

 

When I compare the code from mine and the tutorial, the difference are my use of spaces, and the script scr tags at the beginning of the html, this due to the tutorial is a bit older than current libraries.

My questions are:

- Why is my code not outputting the contents of the messages array (it doesn't do it neither on first connect, nor when i send message, just starts with undefined)

- Why do I get the "undefined" message, in both sets of code - in the tutorial video he does not get it, so I assume it has to do with a version change somewhere, but I'd like to understand it.

 

My code client side, index.html ;)

Spoiler


<!doctype html>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.3.1.min.js" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
<script src="/socket.io/socket.io.js"></script>

<div class="container">
    <br>
    <div class="jumbotron">
        <h1 class="display-4">Send Message</h1>
        <br>
        <input id="name" class="form-control" placeholder="Name">
        <br>
        <textarea id="message" class="form-control" placeholder="Message"></textarea>
        <br>
        <button id="send" class="btn btn-success">Send</button>
    </div>

    <div id="messages">

    </div>
</div>

<script>
    var socket = io()

    $(() => {
        // document ready, short hand version
        $("#send").click(() => {
            var message = { name: $("#name").val(), message: $("#message").val()}
            postMessage(message)
        })  
        getMessages()      
    })

    socket.on('message',addMessage)

    function addMessage(message) {
        $("#messages").append(`<h4> ${message.name} </h4> <p> ${message.message} </p>`)
    }

    function getMessages(){
        $.get('http://localhost:3000/messages', (data) => {
            data.forEach(addMessages) // removed extra ()
        })
    }

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

 

 

My code, server side, server.js

Spoiler


var express = require('express')
var bodyParser = require('body-parser')
var app = express()
var http = require('http').Server(app)      // note that socket.io requires a tie to express and a http server, which is what these 2 lines do
var io = require('socket.io')(http)         // ^---

app.use(express.static(__dirname))
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({extended: false}))

var messages = [
    {name: 'Tim', message: 'Hi'},
    {name: 'Jane', message: 'Hello'}
]

app.get('/messages',(req,res) => {
    res.send(messages)   
})

app.post('/messages',(req,res) => {
    messages.push(req.body)
    io.emit('message',req.body)
    res.sendStatus(200)   
})

io.on('connection', (socket) => {
    console.log('a user connected')        
})

var server = http.listen(3000,() => {
    console.log('server is listening on port', server.address().port)
})

 

 

Tutorial code, client side:

Spoiler


<!doctype html>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous">
<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 src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js" integrity="sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1" crossorigin="anonymous"></script>
<script src="/socket.io/socket.io.js"></script>

<div class="container">
    <br>
    <div class="jumbotron">
        <h1 class="display-4">Send Message</h1>
        <br>
        <input id="name" class="form-control" placeholder="Name">
        <br>
        <textarea id="message" class="form-control" placeholder="Message"></textarea>
        <br>
        <button id="send" class="btn btn-success">Send</button>
    </div>
    <div id="messages">

    </div>
</div>
<script>
    var socket = io()
    $(() => {
        $("#send").click(()=>{
            var message = { name: $("#name").val(), message: $("#message").val()}
            postMessage(message)
        })
        getMessages()
    })

    socket.on('message', addMessage)

    function addMessage(message){
        $("#messages").append(`<h4> ${message.name} </h4> <p> ${message.message} </p>`)
    }

    function getMessages() {
        $.get('http://localhost:3000/messages', (data) => {
            data.forEach(addMessage);
        })
    }

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

 

Tutorial code, server side:

Spoiler


var express = require('express')
var bodyParser = require('body-parser')
var app = express()
var http = require('http').Server(app)
var io = require('socket.io')(http)

app.use(express.static(__dirname))
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({extended: false}))

var messages = [
    {name: 'Tim', message: 'Hi'},
    {name: 'Jane', message: 'Hello'}
]

app.get('/messages', (req, res) =>{
    res.send(messages)
})

app.post('/messages', (req, res) =>{
    messages.push(req.body)
    io.emit('message', req.body)
    res.sendStatus(200)
})

io.on('connection', (socket) => {
    console.log('a user connected')
})

var server = http.listen(3000, () => {
    console.log('server is listening on port', server.address().port)
})

 

 

// Jens

And... as usual, after I beat my head against it for an hour - spend 10 minutes creatingthe elaborate post above I find the problem:

In my client side code, I had the getMessages() function that is called on document ready (only) with this code:


function getMessages(){
        $.get('http://localhost:3000/messages', (data) => {
            data.forEach(addMessages); // removed extra ()
        })
    }

Note the 's' on addMessages (this was the old name for this function) - Stripping that made the document ready actually query the server for the messages, and then of course also displaying them :P

One question remains, where does the "Undefined" come from, that isn't in the tutorial video (but in the code if I run it with my version of node.js)

// Jens
Advertisement

The 'Undefined' comes from JavaScript.  It's the result of invoking the undefined name 'addMessages' for each message returned by the server.  The undefined name 'addMessages' is undefined, so JS returns 'Undefined' when it's used.

Think of it as an error message.

Stephen M. Webb
Professional Free Software Developer

5 minutes ago, Bregma said:

The 'Undefined' comes from JavaScript.  It's the result of invoking the undefined name 'addMessages' for each message returned by the server.  The undefined name 'addMessages' is undefined, so JS returns 'Undefined' when it's used.

Think of it as an error message.

but undefined still shows up after i change addMessages to addMessage.

// Jens
23 hours ago, JensB said:

but undefined still shows up after i change addMessages to addMessage.

Your 'addMessage()' function displays values from 'message'.  What is actually sent by the server?

Stephen M. Webb
Professional Free Software Developer

This topic is closed to new replies.

Advertisement