Bringing it to life
Before we start Building the application code, we need to fully imagine and visualize the process/workflow.
- Getting messages:
- Get/Query/Fetch all the messages from the server.
- Parse and format the messages to present them on the screen.
- Continuously Fetch the messages from the server to keep the messages up-to-date.
- Sending messages:
- Get the user's name from the input field in the header.
- Send the message in the format that the API is expecting.
Getting Messages:
- Create references to the HTML elements that we’ll need.
- nameInput
- messageInput
- sendButton
- chatBox
const nameInput = document.getElementById("my-name-input");
const myMessage = document.getElementById("my-message");
const sendButton = document.getElementById("send-button");
const chatBox = document.getElementById("chat");
Create an
updateMessagesInChatBox()
function. This function will:- fetch messages from server -
fetchMessages()
- loop over the received messages to convert them to
html
elements -formatMessages()
- the function will mark the messages as (incoming/outgoing) or (yours/anyone else's) based on the sender name in the textbox.
- Add the formatted messages to the chatbox. -
updateChatBox()
- OR more accurately, clear and the chatbox and insert the newly formatted messages.
function updateMessages() {
// Fetch Messages
// Loop over the messages. Inside the loop we will
// get each message
// format it
// add it to the chatbox
}- fetch messages from server -
Create a function that uses the FetchAPI to requests messages from the server.
- URL to the Server is https://it3049c-chat.fly.dev
- URL to the link to get the messages is https://it3049c-chat.fly.dev/messages
- sometime, the server might be idle and would take a few minutes to wake up again.
const serverURL = `https://it3049c-chat.fly.dev/messages`;
function fetchMessages() {
return fetch(serverURL)
.then( response => response.json())
}Call
fetchMessages()
fromupdateMessages()
- Notice, because
fetchMessages()
is an asynchronous function that returns a promise rather then the actual result, I had to makeupdateMessages()
anasync
function as well and instruct it to await the results fromfetchMessages()
.
async function updateMessages() {
// Fetch Messages
const messages = await fetchMessages();
// Loop over the messages. Inside the loop we will
// get each message
// format it
// add it to the chatbox
}- try to log the
messages
variable to the console to confirm the structure of each message looks like this
{
"id": 1,
"text": "This is my message",
"timestamp": 1537410673072
}- Notice, because
Create a formatter function that will take the
message
object and the usernamemy-name-input
(from the text field) as parameters and returnHTML
.- the function will need to parse the timestamp to a readable format.
- Obviously,
1537410673072
is not a readable format
- Obviously,
- compare the value of the
messages.sender
and the text input field,my-name-input
:- if it's the same, then use the class
mine
around the message div. - if it's not the same, use the class
yours
around the message div.
- if it's the same, then use the class
function formatMessage(message, myNameInput) {
const time = new Date(message.timestamp);
const formattedTime = `${time.getHours()}:${time.getMinutes()}`;
if (myNameInput === message.sender) {
return `
<div class="mine messages">
<div class="message">
${message.text}
</div>
<div class="sender-info">
${formattedTime}
</div>
</div>
`
} else {
return `
<div class="yours messages">
<div class="message">
${message.text}
</div>
<div class="sender-info">
${message.sender} ${formattedTime}
</div>
</div>
`
}
}- the function will need to parse the timestamp to a readable format.
Now we loop over the array of the messages, format them and add them to the chatbox.
async function updateMessages() {
// Fetch Messages
const messages = await fetchMessages();
// Loop over the messages. Inside the loop we will:
// get each message
// format it
// add it to the chatbox
let formattedMessages = "";
messages.forEach(message => {
formattedMessages += formatMessage(message, nameInput.value);
});
chatBox.innerHTML = formattedMessages;
}
- We need to make sure the function is called.
- otherwise, we won't see any difference.
updateMessages()
Use
setInterval()
to call this function once every 10 seconds to keep the new messages coming.setInterval(updateMessages, 10000);
- the number
10000
in this scenario is what we refer to as a magic number. it's a value of some significance but someone looking at this may not easily understand what this value is- we like to set this value to a variable to make this a bit more readable.
const MILLISECONDS_IN_TEN_SECONDS = 10000;
setInterval(updateMessages, MILLISECONDS_IN_TEN_SECONDS);- the number
Sending Messages
- Create a send function that would:
- take the username, and message text as parameter
- construct a json object with the following properties
sender
,text
, andtimestamp
- send messages to the server here
- using Fetch API
- Using JQuery
function sendMessages(username, text) {
const newMessage = {
sender: username,
text: text,
timestamp: new Date()
}
fetch (serverURL, {
method: `POST`,
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(newMessage)
});
}
function sendMessages(username, text) {
const newMessage = {
sender: username,
text: text,
timestamp: new Date()
}
$.post(serverURL, newMessage);
}
- create an Event Listener to listen to the
click
event on the send button. This event handler will:- send the message to the server and clear the text field to prepare for a new message to be sent
- clear the message text field
sendButton.addEventListener("click", function(sendButtonClickEvent) {
sendButtonClickEvent.preventDefault();
const sender = nameInput.value;
const message = myMessage.value;
sendMessages(sender,message);
myMessage.value = "";
});
Next: Hosting and Submission