2

With Angular how can I subscribe to an array of objects like this one:

[
    'abc/user2': { room: 'abc/user2', user: 'user2' },
    'abc/admin': { room: 'abc/admin', user: 'admin' }
]

Currently this doesn't work :

this.socketService.onRoom().subscribe(rooms => {
    this.rooms = rooms;
});

With socketService:

public onRoom() {
    return new Observable<any>(observer => {
        this.socket.on('room', (data: any) => observer.next(data));
    });
}

Edit:

Mybad, it seems that problem comes from the server (NodeJS/express/socket.io) :

chat-server.ts:

public rooms: Array<{room: string, user:string}> = [];

(...)
this.rooms[room] = {room: room, user: socket.user};
this.io.emit('room', this.rooms)
console.log('[server]rooms :', this.rooms)

Server side, console.log print :

[
    'abc/user2': { room: 'abc/user2', user: 'user2' },
    'abc/admin': { room: 'abc/admin', user: 'admin' }
]

But clientside in socketService, if i do a console.log(data) here :

public onRoom() {
    return new Observable<any>(observer => {
        this.socket.on('room', (data: any) => {
            console.log(data)
            observer.next(data)
        });
    });
}

It return :

[]

But if I emit serverside:

this.io.emit('room', Object.keys(this.rooms))

Clientside it return:

['abc/user2', 'abc/admin']

It's look like i can't emit an array of object from socket.io ?

2
  • 2
    show us onRoom() method in service. Commented Feb 16, 2018 at 14:42
  • @VinkoVorih edited; subscribe work with a simple array of string, but i cant manage to make it work with an array of object Commented Feb 16, 2018 at 14:48

4 Answers 4

2

You can't. You have to turn it into an observable of some kind..

import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs/Observable';

export class AppComponent implements OnInit {

    private readonly data = [
        {
            'abc/user2': { room: 'abc/user2', user: 'user2' }
        },
        {
            'abc/admin': { room: 'abc/admin', user: 'admin' }
        }
    ];
    private data$;

    ngOnInit() {
        this.data$ = new Observable((observer) => {
            observer.next(this.data);
            observer.complete();
        });
    this.data$.subscribe(data => {
        console.log(data);
    });
}

Though there are many other ways (and probably better ways) to do it. Just an example for you since I don't know exactly what you are trying to accomplish.

Sign up to request clarification or add additional context in comments.

Comments

0

You should create observable which you want to return outside of socket.on method.

public onRoom(): Observable<any> {
    BehaviorSubject<any> toReturn = new BehaviorSubject();
    this.socket.on('room', (data: any) => toReturn.next(data));
    return toReturn;
}

Comments

0
private myArray = [
    'abc/user2': { room: 'abc/user2', user: 'user2' },
    'abc/admin': { room: 'abc/admin', user: 'admin' }
];
private myObservable= Observable.of(this.myArray);

You can subscribe to myObservable then.

Comments

0

I finally manage to resolve this problem by not emitting an array of object, but just an object

chat-server.ts

//public rooms: Array<{room: string, user:string}> = [];
public rooms: any = {};

And client side, i convert my object to an array, so that i can iterate throw it in template.

chat-list.component.ts

this.socketService.onRoom().subscribe(rooms => {
    this.rooms = rooms;
    this.roomsArr = Object.entries(this.rooms);

});

Still, I don't understand why i couldn't manage to emit an array of object from socket.io

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.