0

In my chat program, I am trying to create a function, that checks if there exists a conversation in the database. If a conversation exists with peopleName it should get retrieved on the client. If a conversation with that name does NOT exist, a new conversation should get created.

It seems that the 'checkConversation' function is not waiting for the result, because it is creating a new conversation every time, even though the conversation exists.

Client-side:

//Starting conversation
$("#people").on("click", ".list-group-item", function() {
  var peopleName = $(this).children("span").text();
  var peopleID = $(this).children("span").attr("class");
  var conversationExists = false;
  socket.emit("checkConversation", peopleName, function(data) {
    conversationExists = data.result;
    if (conversationExists) {
      console.log("Retrieved existing conversation with ", peopleName);
      return;
      // Check if there is a conversation in the Database where this name is conversationReceiver. ------------------------------------
      // if there is: retrieve conversation/messages
      // else: create conversation.
    } else {
      console.log("NEW conversation with ", peopleName);
      socket.emit("serverCreateConversation", peopleName, peopleID);
      $("#msg").prop("readonly", false);
      $("#msg").attr("placeholder", "Your message");
      $("#send").attr("disabled", false);
      $("#chat").empty();
    }
  });
});

Server-side:

client.on("checkConversation", function(peopleName, fn) {
  var match = false;
  connection.query("SELECT * FROM `conversations` WHERE `conversation_receiver` = '" + peopleName + "'", function(error, results, fields) {
    if (error) {
      console.log(error);
    } else if (results) {
      console.log("Conversation exists!", results);
      match = true;
    } else {
      console.log(fields);
    }
  });
  console.log("match: " + match);
  fn({ result: match });
});
AKX
  • 152,115
  • 15
  • 115
  • 172
JonasSH
  • 206
  • 3
  • 17
  • what is the ouput of data.result in your example? – Mokkun May 10 '17 at 07:32
  • the ouput of data.result is false – JonasSH May 10 '17 at 07:35
  • You're missing the point of callbacks. You don't *wait* on a callback, you execute the follow-up code *in* the callback. – shmosel May 10 '17 at 07:36
  • 1
    Required reading https://xkcd.com/327/, http://stackoverflow.com/q/14220321/18771, http://stackoverflow.com/q/6847697/, the documentation of your mysql database library on how to use parameters in queries. – Tomalak May 10 '17 at 07:36

2 Answers2

2

This seems like the usual asynchronous callback hurdle people stumble upon when starting with Node.js and other Javascript asynchrony.

Server-side, you need to only call fn when you get the result from the database, i.e. in the callback you pass to connection.query:

client.on("checkConversation", function(peopleName, fn) {
  connection.query("SELECT * FROM `conversations` WHERE `conversation_receiver` = '" + peopleName + "'", function(error, results, fields) {
    if (error) {
      console.error(error);
      fn({ result: false, error: true });
      return;
    }
    var match = !!results; // (shorthand to turn a truthy value into true/false)
    console.log("Conversation with " + peopleName + ": " + match);
    fn({ result: match });
  });
});

(I took the liberty of simplifying the code a little, too.)

However, there's another pressing issue: Your code is vulnerable to SQL injection attacks. Please find out how parametrized queries work in the SQL library you're using, and use them instead of building SQL queries with +!

Community
  • 1
  • 1
AKX
  • 152,115
  • 15
  • 115
  • 172
  • Thanks! Yep I'm new to node :-) Using your code, I am now getting the message: 'Conversation with name: true' every time, even though it SHOULDN'T be true. Am I doing it right on the client-side? – JonasSH May 10 '17 at 08:23
1

You're doing it wrong, websocket don't work like AJAX, you need to emit the result from your backend, and listen to it on your frontend

you need a socket.emit on your server code

and you need a socket.on on your client code

Mokkun
  • 708
  • 4
  • 14