Part 2: 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.
In this part, we'll mock/fake the server and the API to focus on the client-side code.
Getting Messages:
- Create references to the HTML elements that we'll need.
- nameInput
- messageInput
- sendButton
- chatBox
💰 Solution (don't open until you really have to)...
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 a function that will take a message object as a function argument and return
HTML
that will be added to the chatbox.
- The JSON structure of the message object is as follows:
{
"id": 1,
"text": "This is my message",
"sender": "Yahya Gilany",
"timestamp": 1537410673072
} - Review the HTML code in the previous part to see how the message should be formatted.
- 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
- the function will need to parse the timestamp to a readable format.
- Obviously,
1537410673072
is not a readable format - You may need to review the
Date
object in JavaScript to see how to parse the timestamp. You can find that on MDN at https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
- Obviously,
💰 Solution (don't open until you really have to)...
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>
`
}
}
- Because we'll be mocking some of the server and API calls, create a function named
fetchMessages()
that will return an array of messages.
💰 Solution (don't open until you really have to)...
function fetchMessages() {
return [
{
id: 1,
text: "This is my message",
sender: "Yahya Gilany",
timestamp: 1537410673072
},
{
id: 2,
text: "This is another message",
sender: "Yahya Gilany",
timestamp: 1537410673072
},
{
id: 3,
text: "This is a message from someone else",
sender: "Someone Else",
timestamp: 1537410673072
}
];
}
-
Create a function
updateMessagesInChatBox()
that would use the array returned fromfetchMessages()
and formats them using theformatMessage()
and injects the resulting response into the UI.- create an array of chat messages objects. and wrap it in a function named fetch messages from server -
fetchMessages()
- loop over the recieved 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 accuretly, 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 using DOM manipulation
} - create an array of chat messages objects. and wrap it in a function named fetch messages from server -
note
You may combine the formatted messages as a single HTML string and inject it, using innerHTML
into the chatbox.
OR
You may create a multiple fragments and append them into the chatbox
💰 Solution (don't open until you really have to)...
function updateMessages() {
const messages = fetchMessages();
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()
Sending Messages
Again we're continuing to mock the server and API calls and we're just focusing on the client-side code of manipulating the DOM.
- Create a send function.
- take the username, and message text as function arguments
- construct a json object with the following properties
sender
,text
, andtimestamp
- add the message to the chatbox
- create an Event Listener to listen to the
click
event on the send button.
- Call the
sendMessages()
function, passing the values of the appropriate fields. - clear the message text field
💰 Solution (don't open until you really have to)...
sendButton.addEventListener("click", function(sendButtonClickEvent) {
sendButtonClickEvent.preventDefault();
const sender = nameInput.value;
const message = myMessage.value;
sendMessages(sender,message);
myMessage.value = "";
});