Zander17
Zander17

Reputation: 1954

Pass a variable to a observable

I'm currently using an observable in the following way:

this._socket.onMessage.subscribe(
    (message) => {

    }
);

which works fine! However, Would it be possible to pass a variable to the observable that would allow for some logic?

For example by passing a variable "name" to onMessage, I could subscribe only to events whos name is something specific? Like this:

this._socket.onMessage(name-variable).subscribe(
    (message) => {
        // only get events that is related to the name-variable
    }
);

Upvotes: 6

Views: 20666

Answers (5)

For anybody needing this, this is how you can pass variables to observables and use the observer at the same time:

function onMessage(message): Observable<any>{
   return new Observable(observer => {
      socket.message(message).subscribe(result => {
         observer.next(result); 
      });
   });
}

This way you can use it like this:

onMessage('Hello World').subscribe(msg => {
   alert(msg);
});

Upvotes: 3

silicakes
silicakes

Reputation: 6902

You can do something like that with a small design shift:

function handleFoo(data) {}

function handleBar(data) {}

const messageGroups = {
  foo: handleFoo
  bar: handleBar
}

this._socket.onMessage.subscribe(
    (message) => messageGroups[message.type](message)
);

this will allow more generic handling of specific message groups, which imo, is a cleaner way to achieve MDNs suggestion: https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications#Receiving_messages_from_the_server

Upvotes: 1

Reactgular
Reactgular

Reputation: 54741

You have to create helper functions that yield the desired effect.

public getMessagesForName(name: string): Observable<any> {
    return this._socket.onMessage.filter((message) => {
        return message.name === name;
    });
}

The more advanced approach would be to create your own class that extends one of the Subject classes. Like EventEmitter or Subject and add the helper functions there. You would then just apply the filter to the this reference.

Here's an example:

 class MessageEvent extends EventEmitter<MessageData> {
       public forName(name: string): Observable<MessageData> {
          return this.filter((message) => {
               return message.name === name;
          });
       }
 }

It all depends on how much re-use you need.

Upvotes: 9

SaxyPandaBear
SaxyPandaBear

Reputation: 377

Edit: See the answer by ThnkingMedia

I'm not so sure if you can do it with the syntax you're looking for, but you could probably do something along the lines of

let flag: boolean = someProperty;
this._socket.onMessage.subscribe(
    (message) => {
        if (flag) { // do something
        }
    }
);

Also, I'm pretty sure on your Observable you can use a filter() call. So the Observable could probably change

myObservable.filter(...).map(...).subscribe(....)
//where myObservable is the Observable object you're working with    

Upvotes: 3

user4676340
user4676340

Reputation:

I didn't quite understand what you meant here, but yes you can pass a value to an Observable. The code is quite simple

returnCustomObservable() {
    return Observable.of('Your value here');
}

However, if I got you correctly, this means you have to rewrite the onMessage function to give it the value you want.

Upvotes: 1

Related Questions