RxJS: How do you wrap a primitive type such as a string in an Observable and listen to changes to that primitive?
Consider the following example. setTimeout
simulates some external event that changes the string s
. However, the console.log
only fires once and not after setTimeout
is called. Why is that?
let s = "Hello World";
Observable.of(s).subscribe(val => {
console.log(val);
});
// some external event changes variable s
setTimeout( () => {
s = "Wat?";
}, 1000);
// Output: prints "Hello World" to console, but not "Wat?"
This question might sound a bit dumb, but I searched for 2 hours through all kinds of RxJS docs and examples and most of them play with Arrays or Objects. This is not what I want. I don't want to change attributes, functions, arrays or anything like that. Just a plain string or boolean or number.
I do realize that this question has an accepted answer but here is the proper way to observer a string for changes using RxJS.
Create a variable for type ReplaySubject
stringVariable$: ReplaySubject<String> = new ReplaySubject<String>();
Assign all new values to stringVariable
via a function to catch the update event.
assignNewValue(newValue: String) {
this.stringVariable$.next(newValue);
}
Subscribe to this Observable
stringVariable$.subscribe((newValue: String) => {
console.log(newValue);
});
Alternatively you can use a BehaviourSubject if your string variable has a initial value to start with.
You are thinking about streams incorrectly. The whole point of the stream is that you should not be mutating objects directly (strings can't actually be mutated as @Pointy already mentioned but this is a more general point).
You need to shift your thinking to seeing data as immutable and the stream as representing the change which your react to in the subscriber.
In your example, if you wanted to "mutate" a string, what you are really trying to do is capture a set of changes and surface them through the next
handler of the subscribe
method. Where those changes come from is irrelevant from the string's perspective, it only cares that events are being passed through it.
i.e. I could do the following to emit different strings:
Rx.Observable.timer(1000)
.mapTo('Wat')
.startWith('Hello World!')
.subscribe(x => console.log(x));
What you need to determine is what the source of your changes is and what events it should emit. From there Rx can help you massage that data into something that you can use downstream.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With