I have created django consumers.py and a frontend in html and css to disply messages sent by a user, the profile picture of the sender and the username of the sender but anytime i open the browser, the message displays well but the username appears as undefined . eg @Undefined: How are you
this is my consumers.py
`User = get_user_model()
class DiscussionRoomConsumer(AsyncWebsocketConsumer):
async def connect(self):
self.room_name = self.scope['url_route']['kwargs']['room_name']
self.room_group_name = f"discussion_room_{self.room_name}"
# Join room group
await self.channel_layer.group_add(
self.room_group_name,
self.channel_name
)
await self.accept()
# Get or create the VirtualRoom instance based on the provided room_name
virtual_room = await self.get_virtual_room()
if virtual_room is not None:
# Send existing messages and old messages to the new user
old_messages = await self.get_old_messages(virtual_room)
for message in old_messages:
await self.send(text_data=json.dumps({
'message': message['content'],
'user_id': message['user'],
'user_picture': await self.get_user_profile_picture(message['user']),
}))
async def disconnect(self, close_code):
# Leave room group
await self.channel_layer.group_discard(
self.room_group_name,
self.channel_name
)
# Receive message from WebSocket
async def receive(self, text_data):
text_data_json = json.loads(text_data)
message = text_data_json['message']
user_id = self.scope["user"].id
# Get the VirtualRoom instance based on the extracted room name asynchronously
virtual_room = await self.get_virtual_room()
# Check if the VirtualRoom instance exists
if virtual_room:
# Save message to the database with the VirtualRoom instance asynchronously
await self.save_interaction_to_database(user_id, virtual_room, message)
# Send message to the room group
user_picture = await self.get_user_profile_picture(user_id)
await self.channel_layer.group_send(
self.room_group_name,
{
'type': 'chat.message',
'message': message,
'user_id': user_id,
'user_picture': user_picture,
}
)
else:
# Handle the case where the VirtualRoom does not exist
print(f"VirtualRoom with slug '{self.room_name}' does not exist.")
# Receive message from the room group
async def chat_message(self, event):
message = event['message']
user_id = event['user_id']
user_picture = event['user_picture']
# Send the message to WebSocket
await self.send(text_data=json.dumps({
'message': message,
'user_id': user_id,
'user_picture': user_picture,
}))`
and this is my frontend:
<!DOCTYPE html>
{% load static %}
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="{% static 'css/discussionroom.css' %}">
<title>Discussion Room</title>
</head>
<body>
<div id="discussion-room">
<div id="chat-box">
{% for message in messages %}
<div>
<img src="{{ message.user_picture.url|default:'/static/images/avatar.svg' }}" alt="User Picture" style="width: 30px; height: 30px;">
<strong>{{ message.username }}:</strong>
{{ message.message }}
</div>
{% endfor %}
</div>
<input type="text" id="message-input" placeholder="Type your message...">
<button onclick="sendMessage()">Send</button>
</div>
<script>
// Get the room name from the URL
const pathArray = window.location.pathname.split('/');
const roomNameIndex = pathArray.indexOf('discussions') + 1;
const roomName = pathArray[roomNameIndex].split('@')[1];
// Log the extracted room name
console.log('Extracted room name:', roomName);
// Create a new WebSocket connection
const socket = new WebSocket(`ws://${window.location.host}/ws/discussions/${roomName}/`);
socket.onmessage = function(event) {
const data = JSON.parse(event.data);
displayMessage(data.user_picture, data.message);
};
function sendMessage() {
const message = document.getElementById('message-input').value;
if (message.trim() !== '') {
socket.send(JSON.stringify({'message': message}));
document.getElementById('message-input').value = '';
}
}
function displayMessage(userPicture, message) {
console.log('Received user picture:', userPicture);
const messageDiv = document.createElement('div');
// Set the userPicture URL
const imageUrl = userPicture || '/static/images/avatar.svg';
//console.log('Selected image URL:', imageUrl);
const imgElement = new Image();
imgElement.src = imageUrl;
// Add an event listener to handle image load errors
imgElement.addEventListener('error', function() {
//console.warn('Error loading image. Using default avatar.');
messageDiv.innerHTML = `<img src="/static/images/avatar.svg" alt="Default Avatar" style="width: 30px; height: 30px;"> ${message}`;
document.getElementById('chat-box').appendChild(messageDiv);
});
// Add an event listener to handle image load success
imgElement.addEventListener('load', function() {
imgElement.className = 'user-profile-img'; // Add this line
messageDiv.innerHTML = `<img src="${imageUrl}" alt="User Picture" style="width: 30px; height: 30px; border-radius: 50%; object-fit: cover; "> ${message}`;
document.getElementById('chat-box').appendChild(messageDiv);
});
}
</script>
</body>
</html>