I often use combineLatest to combine 3 or 4 Observables to calculate a simple condition.
If one of the 'combined' Observables doesn't emit then this will block until it does. It can be very tricky to debug if later down the line something that has always emitted immediately stops emitting.
Side-note: I'm specifically needing this for UI related logic, where there may be observables that represent things like screen width / scroll position / etc. So they're supposed to always be there - but if it breaks suddenly (especially on mobile) it's difficult to track down what's blocking it.
So what I need is something like combineLatestImmediate that errors if all inputs aren't immediately available. When I say 'available right away' it's typically something that comes from a centralized data store, or a behaviorsubject (which of course will always have a value). But when it breaks...ugh.
Is there a better way than:
combineLatest(obs1, obs2, obs3)
.pipe(timeoutWith(0, throwError('Expected obs all to be available')))
or even:
// note: take(1) is required or the wrong observable
// may get reported if the source hasn’t closed
combineLatest(obs1.pipe(take(1), timeoutWith(0, throwError('obs1 has no value'))),
obs2.pipe(take(1), timeoutWith(0, throwError('obs2 has no value'))),
obs3.pipe(take(1), timeoutWith(0, throwError('obs3 has no value'))));
You could put a non zero value for timeout if you wanted a grace period, or make this into a custom operator. But I'm finding a need more and more for this.
It's a safety / sanity thing, to save time debugging.
Also I'm not looking for forkJoin (which short-circuits if any of the inputs are EMPTY). I'm talking about when a value is just not immediately available - usually .
Related
Assuming the common "Order" aggregate, my view of events is that each should be representative of the command that took place. E.g. OrderCreated, OrderePicked, OrderPacked, OrderShipped.
Applying these events in the aggregate changes the status of the order accordingly.
The problem:
I have a projector that lists all orders in the system and their statuses. So it consumes the events, and like with the aggregate "apply" method, it implements the logic that changes the status of the order.
So now the logic exists in two places, which is... not good.
A solution to this is to replace all the above events with a single StatusChanged event that contains a property with the new status.
Pros: both aggregate and projectors just need to handle one event type, and set the status to what's in that event. Zero logic.
Cons: the list of events is now very implicit. Instead of getting a list of WHAT HAPPENED (created, packed, shipped, etc.), we now have a list of the status changes events.
How do you prefer to approach this?
Note: this is not the full list of events. other events contain other properties, so clearly they don't belong to this problem. the problem is with events that don't contain any info, just change the status of an order.
In general it's better to have more finer-grained events, because this preserves context (and means that you don't have to write logic to reconstruct the context in your consumers).
You typically will have at most one projector which is duplicating your aggregate's event handler. If its purpose is actually to duplicate the aggregate's event handler (e.g. update a datastore which facilitates cross-aggregate querying), you may want to look at making that explicit as a means of making the code DRY (e.g. function-as-value, strategy pattern...).
For the other projectors you write (and there will be many as you go down the CQRS/ES road), you're going to be ignoring events that aren't interesting to that projection and/or doing radically different things in response to the events you don't ignore. If you go down the road of coarse events (CRUD being about the limit of coarseness: a StatusChanged event is just the "U" in CRUD), you're setting yourself up for either:
duplicating the aggregate's event handling/reconstruction in the projector
carrying oldState and newState in the event (viz. just saying StatusChanged { newState } isn't sufficient)
before you can determine what changed and the code for determining whether a change is interesting will probably be duplicated and more complex than the aggregate's event-handling code.
The coarser the events, the greater the likelihood of eventually having more duplication, less understandability, and worse performance (or higher infrastructure spend).
So now the logic exists in two places, which is... not good.
Not necessarily a problem. If the logic is static, then it really doesn't matter very much. If the logic is changing, but you can coordinate the change (ex: both places are part of the same deployment bundle), then its fine.
Sometimes this means introducing an extra layer of separation between your "projectors" and the consumers - ex: something that is tightly coupled to the aggregate watching the events, and copying status changes to some (logical) cache where other processes can read the information. Thus, you preserve the autonomy of your component without compromising your event stream.
Another possibility to consider is that we're allowed to produce more than one event from a command - so you could have both an OrderPicked event and a StatusChanged event, and then use your favorite filtering method for subscribers only interested in status changes.
In effect, we've got two different sets of information to track to remember later - inputs (information in the command, information copied from local caches), and also things we have calculated from those inputs, prior state, and the business policies that are now in effect.
So it may make sense to separate those expressions of information anyway.
If event sourcing is a good approach for the problems you are solving, then you are probably working on problems that are pretty important to the business, where specialization matters (otherwise, licensing an off the shelf product and creating adapters would be more cost effective). In which case, you should probably be expecting to invest in thinking deeply about the different trade offs you need to make, rather than hoping for a one-size-fits-all solution.
I've googled the issue expecting that there's been a gazillion curious people before me asking it too. For some reason, most hits are on scan vs reduce (which I clearly understand). So there's a risk that I totally misunderstood the docs.
According to the docs, scan(...) will snatch an emitted value, do stuff to it and then, optionally pass it on to the next person in line. Meanwhile, subscribe(...), although accepting parameters for handling of errors and completion, does the very same thing.
I understand the "difference" between them but it appears to me as rather insignificant from the aspect of development tooling. Is it as simple as that the former only a convenience method for cases where the latter would require mundane coding? Or is there a fundamental difference between them (as in: something I can do with scanning that I can't achieve subscribing)?
Scan() and Subscribe() are quite different concepts in RxJS.
Scan is an operator for combining values coming through the stream with previous values that came through the stream, and then outputting some combination of them (I think scan and reduce are the only operators that does this). Subscribe only works on the current value that comes through the stream.
Subscribe is a special method and one of the most important concepts in RxJS. Subscribe comes at the end of the Observable stream, this is where you can use the resulting value for something. From all other operators you return something that can be passed down the chain, but you do not return from subscribe.
If you are working with cold Observables (which you very often are), you need to subscribe to it in order for the code to run at all. If you have no subscriptions on a cold observable, then none of the code in your Observable stream will run.
The syntax for using them is also different. Scan is an operator that you chain inside the pipe() method like map, reduce, filter, tap, mergeMap, flatMap, etc. It looks like:
myObservable$.pipe(map(...), scan(...), flatMap(...));
Subscribe is a method like pipe that you dot chain, like:
myObservable$.pipe(...).subscribe(...);
All over the Rx.Net literature there are references to what is commonly know as the temperature of an observable.
There are cold observables (like the ones created by Observable.Interval() and similar factory methods), which will create side effects every time that a new Subscription is created.
On the other side of the spectrum there are hot observables (like Subject<T>) which will onboard new subscriptions as they come.
There are also warm observables, like the ones returned by RefCount() which will execute the initialisation every time one subscription is created, but only if there was no other active subscription. The behaviour of these warm observables is explained here by Dave Sexton:
Alternatively, you can call Publish then RefCount to get an IObservable that is shared among multiple consecutive observers. Note that this isn't truly a hot observable - it's more like a warm observable. RefCount makes a single subscription to the underlying observable while there's at least one observer of your query. When your query has no more observers, changing the reference count to 0, the underlying subscription is disposed. If another observer subscribes to your query later, moving the reference count from 0 to 1 again, then RefCount makes a new subscription to the underlying observable, causing subscription side-effects to occur again.
Are there any other temperatures that one should be aware of? Is it possible to obtain programmatically the temperature of an Observable?
Easy question first:
Is it possible to obtain programmatically the temperature of an Observable?
No. Best you can do is subscribe and see what happens.
The observable 'contract' specifies that when you subscribe to an observable you get zero or more OnNext messages, optionally followed by either one OnCompleted or one OnError message. The contract doesn't specify anything about how multiple or earlier/later subscribers are treated, which is what observable 'temperature' is mostly concerned with.
Are there any other temperatures that one should be aware of?
I wouldn't even think of it in such concrete or discrete terms as you have specified.
I think of it in terms of on-subscribe effects: The coldest of observables have all their effects happen on subscribe (like Observable.Return(42)). The hottest of observables have no effects happening on subscribe (new Subject<int>()). In between those two poles is a continuum.
Observable.Interval(TimeSpan.FromMilliseconds(100)) for example will emit a new number every 100 milliseconds. That example, unlike Observable.Return(42), could be mostly 'warmed-over' via .Publish().RefCount(): The first subscriber starts the numbers, but the second subscriber will see the only the latest numbers, not starting from 0. However, if instead of .Publish() you did .Replay(2).RefCount(), then you have some on-subscribe effects going on. Do the Publish and Replay observables have the same 'temperature'?
TL;DR: Don't focus on the classifications that much. Understand the difference between the two and know that some observables have colder properties and some have warmer ones.
Below are the advantages i have read in URL: Angular - Promise vs Observable
promise:
returns a single value
not cancelled
more readable code with try/catch and async/await
observable
works with multiple values over time
cancellable
supports map, filter, reduce and similar operators
use Reactive Extensions (RxJS)
an array whose items arrive asynchronously over time
In observable i see 3 & 4 Point as supports operators and RXJS. I just have a basic question like can't i use RXJS and operators with promises? what is the meaning of point 5
In short, no you can't use those operators (like map, filter) directly on a Promise.
Rxjs does provide an operator toPromise which does convert an Observable to a Promise - if that is your preference.
I think point 5 is actually conflated with point 1. Point 1 is the crux of what Observables are all about: dealing with 0 to n values over time.
You may not think that to be useful if you're used to using Promises simply for Ajax requests - e.g. hit an endpoint and get a value back. But in the case of Observables, you can use them in any context - for example, DOM events.
If you were to create an Observable via listening to a Mouseover event, then you'd be receiving n values over any given length of time - and then you could react to these events.
When thinking in terms of Ajax requests, the classic example is that of the look ahead search input which is detailed in the link of your question.
As #Rich mentioned, rxjs Operators are aimed for continues data streams (e.g. take takes the first n next of an Observable). As such, not all operators are useful for Promise-based results.
However, given that some operators are compact/neat even for Promise, you can use the following:
import { from, firstValueFrom, delay } from "rxjs";
...
// converts to Observable and back to Promise
firstValueFrom(from(myPromise).pipe(delay(1000))
I am looking for a pub/sub mechanism that behaves like a promise but can resolve multiple times, and behaves like an event except if you subscribe after a notification has happened it triggers with the most recent value.
I am aware of notify, but deferred.notify is order-sensitive, so in that way it behaves just like an event. eg:
d.notify('notify before'); // Not observed :(
d.promise.progress(function(data){ console.log(data) });
d.notify('notify after'); // Observed
setTimeout(function(){ d.notify('notify much later') }, 100); // Also Observed
fiddle: http://jsfiddle.net/foLhag3b/
The notification system I'd like is a good fit for a UI component that should update to reflect the state of the data behind it. In these cases, you don't want to care about whether the data has arrived yet or not, and you want updates when they come in.
Maybe this is similar to Immediate mode UIs, but is distinct because it is message based.
The state of the art for message based UI updating, as far as I'm aware, is something which uses a promise or callback to initialize, then also binds an update event:
myUIComponent.gotData(model.data);
model.onUpdate(myUIComponent.gotData); // doing two things is 2x teh workz :(
I don't want to have to do both. I don't think anyone should have to, the use case is common enough to abstract.
model.whenever(myUIComponent.gotData); // yay one intention === one line of code
I could build a mechanism to do what I want, but I wanted to see if a pub/sub mechanism like this already exists. A lot of smart people have done a lot in CS and I figure this concept must exist, I just am looking for the name of it.
To be clear, I'm not looking to change an entire framework, say to Angular or React. I'm looking only for a pub/sub mechanism. Preferably an implementation of a known concept with a snazzy name like notifr or lemme-kno or touch-base.
You'll want to have a look at (functional) reactive programming. The concept you are looking for is known as a Behavior or Signal in FRP. It models the change of a value over time, and can be inspected at any time (continuously holds a value, in contrast to a stream that discretely fires events).
var ui = state.map(render); // whenever state updates, so does ui with render() result
Some popular libraries in JS are Bacon and Rx, which use their own terminology however: you'll find properties and observables.