West Midlands | 26 March SDC | Iswat Bello | Sprint 2 | chat app#83
West Midlands | 26 March SDC | Iswat Bello | Sprint 2 | chat app#83Iswanna wants to merge 39 commits into
Conversation
- Exclude node_modules/ and package-lock.json from version control - Ignore environment variables (.env) and system files (.DS_Store) - Exclude build artifacts (dist/, build/) and log files (*.log) - Ignore VS Code workspace settings (.vscode/) - Reduce repository size and prevent committing sensitive data
- Import Express library - Create Express app instance - Initialize messages array to store chat data - Configure server port (default: 3000) - Start server with app.listen()
- Add JSON body parsing middleware - Implement POST /messages route with input validation - Validate text and sender fields are provided and non-empty - Create message object with id, sender, text, likes, and dislikes - Store message in messages array - Return created message with 201 status code - Return 400 error for invalid requests
- Implement GET /messages route - Return all messages from the messages array - Enable clients to fetch chat history
- Add index.html with semantic HTML structure - Include meta tags for charset and viewport - Link external stylesheet (styles.css) - Link deferred JavaScript file (script.js) - Create form with sender name and message inputs - Add submit button for sending messages - Create messages container div for displaying chat history
- Create getAllMessages async function to fetch messages from backend - Parse JSON response from /messages endpoint - Clear message container and render new messages - Display sender name and message text for each message - Add error handling for fetch failures - Call getAllMessages on page load to populate initial messages
- Import cors module for CORS support - Fix environment variable casing (process.env.port → process.env.PORT) - Add CORS middleware before other middleware - Move message creation logic inside POST route handler - Fix indentation for code inside route handlers - Properly close POST route handler with closing brace
- Configure Node.js project with ES modules ("type": "module")
- Add Express 5.2.1 for HTTP server framework
- Add CORS 2.8.6 for cross-origin request handling
- Enable npm package management for backend
- Add id="chat-form" to form for JavaScript event listener access - Change textarea to input element for message field - Maintain labels and input structure for sender name and message
- Get form, sender input, and message input elements from DOM - Add submit event listener to chat form - Prevent default form submission behavior - Extract sender name and message text from input values - Send POST request to /messages endpoint with JSON payload - Include Content-Type header for JSON data - Refresh message list on successful submission - Clear input fields after sending message
- Replace single getAllMessages() call with setInterval - Fetch messages from backend every 5000ms (5 seconds) - Enable live chat updates without manual refresh - Keep frontend synchronized with backend message list
- Change mismatched textarea closing tag to self-closing input tag
- Add scripts section with start command - Enable running backend with npm start instead of node server.js - Simplify server startup process - Remove trailing newline from file
- Change getAllMessages() fetch URL from localhost to Render production URL - Update form submission fetch URL to production backend - Enable frontend to communicate with deployed Render backend - Remove dependency on local development server
…king - Add lastIdSeen variable to track last viewed message ID - Update getAllMessages() to use ?since query parameter - Only fetch messages newer than lastIdSeen from backend - Remove messageContainer.textContent clearing to prevent flicker - Update lastIdSeen after each message is displayed - Reduce data transfer by only fetching new messages - Improve performance with incremental polling
- Parse since query parameter from request - Convert since value to number, default to -1 if undefined - Filter messages array to only return messages with id > sinceId - Handle edge case where since=0 evaluates as falsy - Enable pagination and incremental message loading - Reduce payload size by sending only new messages
- Wrap form submission logic in try-catch block - Handle network errors and fetch failures gracefully - Log errors to console for debugging - Prevent app from crashing on failed message submission - Improve user experience with better error handling - Reformat fetch call for better readability
- Replace setInterval with setTimeout for sequential polling - Add setTimeout in try block to schedule next poll after successful fetch - Add setTimeout in catch block to retry polling after error - Call getAllMessages() once on page load instead of starting interval - Ensure each poll waits for previous request to complete - Prevent overlapping requests and race conditions - Improve reliability with error recovery
- Add callBacksForNewMessages array to store pending response handlers - Modify GET /messages endpoint to implement long polling - When no new messages available (messagesSinceId.length === 0), store response callback - When new messages arrive, send them immediately via callback - Enable real-time message delivery without constant polling - Reduce server load by holding requests until new data is available
…lopment - Change getAllMessages() fetch URL from Render to localhost:3000 - Change form submission fetch URL from Render to localhost:3000 - Remove getAllMessages() call after successful message submission - Rely on long polling to fetch new messages automatically - Enable local development workflow - Simplify form submission logic
- Create route to handle message like requests - Extract message ID from URL parameter - Convert ID string to number for comparison - Find message by ID in messages array - Increment likes count for the message - Enable users to like messages in real-time
…like - Check if messageWithIdAsNumber exists after incrementing likes - Notify all waiting clients via callBacksForNewMessages callbacks - Send updated message with 200 status on success - Return 404 error if message not found - Enable real-time like updates via long polling - Improve error handling for invalid message IDs
- Extract current like count from likeSpan text content - Increment likes count immediately when user clicks Like button - Update UI before server response for instant feedback - Maintain consistency with backend data on next poll - Improve user experience with responsive interface
- Style message containers with border, padding, and rounded corners - Add light gray background color (#f9f9f9) to messages - Add spacing between message elements with margin-right - Style buttons with blue background (#007bff) and white text - Add cursor pointer and rounded corners to buttons - Improve visual presentation of chat interface
- Change getAllMessages() fetch URL from Render to CodeYourFuture hosting - Update like button fetch URL to CodeYourFuture backend - Update form submission fetch URL to CodeYourFuture backend - Enable frontend to communicate with CodeYourFuture deployed backend - Replace Render production URL with CodeYourFuture hosting domain
- Remove npm start script configuration - Simplify package.json to only include dependencies - Users will run server with direct node command instead
|
| const messagesSinceId = messages.filter((message) => message.id > sinceId); | ||
|
|
||
| if (messagesSinceId.length === 0) { | ||
| callBacksForNewMessages.push((value) => res.send(value)); |
There was a problem hiding this comment.
What do you expect to happen if no new message arrives within 30 minutes?
| callback([messageWithIdAsNumber]); | ||
| } | ||
| res.status(200).send(messageWithIdAsNumber); |
There was a problem hiding this comment.
Some of the message properties are not needed to update likes count. Can you improve this code to send only the necessary data?
| const messageWithIdAsNumber = messages.find( | ||
| (message) => message.id === idAsNumber, | ||
| ); |
There was a problem hiding this comment.
Is there a more efficient way to locate the desired message object by its id?
I have updated the PR description based on your feedback. Thank you. |
- Add check for req.body existence before destructuring - Add type validation to ensure text and sender are strings - Replace simple falsy check with .trim() for whitespace validation - Return specific error messages for each validation failure - Improve error handling clarity with separate validation steps - Prevent type coercion errors and invalid data submission
- Trim whitespace from sender and message inputs - Prevent empty submissions and show alert if fields are blank - Return early from submit handler when validation fails - Improve UX and prevent sending invalid messages
- Add API_BASE_URL placeholder constant
- Replace hardcoded production URLs with `${API_BASE_URL}` for:
- GET /messages
- POST /messages/:id/like
- POST /messages (form submission)
Learners, PR Template
Self checklist
Changelist
This PR implements a fully functional real-time chat application with a Node.js/Express backend and vanilla JavaScript frontend. The application supports sending messages, viewing chat history, and liking messages with real-time updates using long polling.
Deployed sites
Additional Feature implemented
Interactive Reaction System: I implemented a "Like" button for each message. This required creating a custom API endpoint (/messages/:id/like) and logic to update the state of existing messages without re-rendering the entire chat.
Performance Optimisation (Long Polling): To make the chat feel "live" without overworking the server, I implemented Long Polling. This ensures messages appear instantly while reducing the number of empty requests.