JD333
JD333

Reputation: 533

Socket IO Node Angular Chat Service

I'm posting about a situation i ran into when implementing a guide I found online: https://codingblast.com/chat-application-angular-socket-io/

It was working well. I was able to connect to the node server when going to the right component on my website. A lot of the code I'm going to post is very similar to what I found on the website.

Also I got to the point where I was able to see "started on port : 3000" and "user connected" This works. But I can't seem to send messages to the server.

Here is the file where I think the problem is happening:

index.js

let express = require('express');
let app = express();

let http = require('http');
let server = http.Server(app);

let socketIO = require('socket.io');
let io = socketIO(server);

const port = process.env.PORT || 3000;

io.on('connection', (socket) => {
  console.log('user connected');

  socket.on('new-message', (message) => {
    console.log(message);
  });
});

server.listen(port, () => {
  console.log(`started on port: ${port}`);
});

chat.componenet.html

<div class="main-container--chat">
  <div class="message-box-container">
    <div *ngFor="let message of messages">
      {{message}}
    </div>
  </div>

  <div class="chat-input">
    <input [(ngModel)]="message" (keyup)="$event.keyCode == 13 && sendMessage()"/>
    <button (click)="sendMessage()">Send</button>
  </div>
</div>

chat.component.ts

export class ChatComponent implements OnInit {
  message: string;
  messages: string[] = [];

  constructor(private chatService: ChatService) {
  }

  ngOnInit() {
    this.chatService
      .getMessages()
      .subscribe((message: string) => {
        this.messages.push(message);
      });
  }

  sendMessage() {
    this.chatService.sendMessage(this.message);
    this.message = '';
  }
}

and finally chatService.service.ts

 export class ChatService {
      private url = 'http://localhost:3000';
      private socket;

      constructor() {
        this.socket = io(this.url);
      }

      public sendMessage(message) {
        this.socket.emit('new-message', message);
      }

      public getMessages = () => {
        return 

    Observable.create((observer) => {
      this.socket.on('new-message', (message) => {
        observer.next(message);
      });
        });
      }
    }

I did my best to keep the posted code specific. I hope it's not too much to glare at. Especially on a Friday.

But again, when running index.js via Node. I am able to view that a "user connected" and that port:3000 started. But, when I send a message, the server never receives it. Also when I try to console.log("somethign random"); inside:

  socket.on('new-message', (message) => {
    console.log(message);
  });

I don't see that random console log message appear. I don't think my naming is incorrect for new-message.

I'm new to this so I hope it's not something obvious. I'd really appreciate any help.

Edit: restarted server and got the logging to work. But all code staying the same and adding

io.emit(message);

to

  socket.on('new-message', (message) => {
    console.log(message);
  });

I'm still not getting the messages on the html.

Upvotes: 3

Views: 1107

Answers (1)

Alexander Staroselsky
Alexander Staroselsky

Reputation: 38787

You need to additionally emit/broadcast the new-message event with the payload of the string message on the server using emit on io, specifically io.emit('new-message', message), within the socket socket.on('new-message', (message) => { }). This way the client connected to this socket can receive the new-message events within the observable stream.

io.on('connection', (socket) => {
  console.log('user connected');

  socket.on('new-message', (message) => {
    console.log(message);
    io.emit('new-message', message); // emit event
  });
});

You shouldn't need to make any changes to your Angular/client code. Just remember to implement some sort of tear down of the observable using something along the lines of complete() within the body of complete() or terminating/filtering operators such as takeUntil. Otherwise you can/will have potential memory leaks.

Hopefully that helps!

Upvotes: 2

Related Questions