DEV Community

Cover image for You Don't Have To Use Observables In Angular
Dev By RayRay
Dev By RayRay

Posted on • Originally published at hasnode.byrayray.dev

You Don't Have To Use Observables In Angular

In Angular, you can perform asynchronous actions in two different ways, Observables, and Promises.

Most people pick Observables because every example on blogs and documentation tells you to do so. But why? Are Promises that bad? Or Observables that good?

In this post, I want to dive with you into the why! Why and when should we use Observables, and when are Promises just fine.

Let's start with comparing the two with each other.

divider-byrayray.png

Observables VS Promises

Let's start with the Observables.

Observables

Angular is using under the hood RxJS. RxJS comes with a great set of features like Observables.

Observables can perform asynchronous and synchronous actions in comparison to Promises. Promises can only perform asynchronous actions.

When Observables are created, it does nothing until a piece of code decides to subscribe to it. You can cancel a subscription to Observables, or when an error is happening, it's automatically unsubscribed.

Observables handle a stream of values. It updates very quickly at a later point in time.

To summarise:

Observables behaviors

  • Multiple values
  • Can be canceled
  • Great for real-time information
  • Can be subscribed to from multiple places
  • Errors unsubscribe automatically
  • Observables are declarative. They are only performed when something is subscribed to it.
  • Have a built-in mechanism to perform transformations to the data (map, forEach, filter, reduce, retry, and retryWhen operators)
  • Can be both asynchronous and synchronous

Promises

A Promise is a general JavaScript concept introduced since ES2015 (ES6). It's ideal for performing asynchronous actions. It doesn't have subscribers like Observables.

A Promise can't be canceled like an Observable. It can be resolved or rejected, nothing more, nothing less. It can handle single values instead of a stream of values.

Promises are performed on creation instead of subscription like Observables are.

If you want to learn more about Promises, check a more detailed post I wrote earlier

To summarise:

Promises behaviors

  • Single value
  • Can't be canceled
  • Great for single time information
  • Can't re-use or distribute information
  • Promises are performed on the creation
  • Is always asynchronous

divider-byrayray.png

When Use A Promise Or Observable?

As we saw earlier, the most significant difference between a Promise and an Observable is handling a single value and a stream of values.

Use A Observable

An Observable is ideal for situations where the data changes during its lifetime.

Situations to use

  • Real-time data from a WebSocket, for example. Think about dashboards, chat messages, notifications, video subtitles, sound visualizations.
  • Or actions that are performed very often by a user. For example, think about collapsable menus, dark and light modes.

These situations require data to update in a short amount of time, at least in the same lifetime of the subscriptions.

Use A Promise

Since a Promise can handle a single value, there are pretty many situations to use it.

Situations to use

  • Forms submission: Creating, editing, and deleting data entities don't require a constantly updated stream of data. The form data is sent to the API; it's successfully done or not.
  • API requests for data that doesn't change real-time: a large amount of data to show an overview page or a detail page

All of these situations don't require that data to change that often. Data is collected by an API call, displayed, and done. It's that simple.

divider-byrayray.png

Why Is Everyone Using Observables For Everything?

So this raises for me the question. "Why is everyone using Observables for everything?"

Yes, I'm guilty on this topic myself! I have done singular requests using an Observable. Was it needed? No!

Keeping a subscription open, while the data is not changing in the lifetime of that Observable, is not correctly using the power of a browser. Besides that, most developers (myself included) will forget to unsubscribe from their Observable quite often.

My rule of thumb mostly is: "If you don't need it, don't include or use it!"

Let's not waste our resources but use everything for its purpose.

divider-byrayray.png

Summarize

Okay, let's make this easy for everyone.

Use an Observable for data that is changing real-time or more often during its lifetime. Don't waste resources! Use A Promise if the data isn't changing during the lifetime of a component!

It could be possible that I'm missing the point or being wrong 😅. Would you please let me know in the comments what I'm missing?

divider-byrayray.png

Thanks!

hashnode-footer.png
*I hope you learned something new or are inspired to create something new after reading this story! 🤗 If so, consider subscribing via email (scroll to the top of this page) or follow me here on Hashnode.
*

Did you know that you can create a Developer blog like this one, yourself? It's entirely for free. 👍💰🎉🥳🔥

If I left you with questions or something to say as a response, scroll down and type me a message. Please send me a DM on Twitter @DevByRayRay when you want to keep it private. My DM's are always open 😁

Latest comments (14)

Collapse
 
cesee profile image
Cesar Maroun • Edited

I totally agree.

Code, like everything else, should be simple and direct.
In almost 100% of the daily tasks one can use a simple Promise instead of over-engineering with Observables.
Most views are basically (click/event => get results using criteria => show results).

Promises tend to make your code end up looking very similar to the logic, especially with using await/async (click => wait for result => show result), and Observables tend to create indirect implmentations (when the text changes put it somewhere, something else will make sure the results are updated later). For me, indirect implementations are very very bad.

Observables are very powerful for infrastructure-like stuff (like Base classes, global services, etc...) and they should be prefered there.

It's simply another case of the right tool for the job.

Collapse
 
saulodias profile image
Saulo Dias • Edited

While I completely agree with you when you say it's not necessary for everything, I highly recommend developers in my team to prefer Observables over Promises when working with Angular. The top reasons are consistency and flexibility.
Anything you do with a Promise can be done with an Observable, but that's not true the other way around.
Also, you don't need to unsubscribe from Observables which use the HttpClient, which seems to be the only example of extensive use of Promises you've given, but that doesn't free you up from unsubscribing in other situations. That is, nothing has changed.
In the end, I'll stick to Obsevables in my HTTP calls because pipe, map, and other RxJs operators just make my life a lot easier when it comes to preprocessing responses, and is specially helpful when the requests have asynchronous parameters, which is not uncommon.
And last but not least, I'd rather have a new junior developer learn RxJs well to deal with our Angular code base, than having them learn both, if they have that technical debt. They can learn Promises later and that will not be an impediment to deal with our code base.
The only time I make use of Promises is when I don't already have RxJs as an inevitable dependency. For example when I'm writing a simple script or smaller project, and I see it would be overkill to use RxJs. If there are not restrictions I'll use Promises, which are way more elegant than callbacks, but I'll use callbacks if there's a good reason to.
I think not using RxJs for everything in Angular would be similar to writing Assembly code to optimize a part of and application you're writing in C, because of resources or speed. At this point you have to ask yourself: Is that really making much of a difference?
Everyone is entitled to their preferences though.

Collapse
 
pix303 profile image
Paolo Carraro • Edited

Interesting article, thanks! A doubt: for http requests do you use HttpClient and return a toPromise() of that? (...so your article pops out others questions... as far i can see it's an old and resolved debate about HttpClient :)

Collapse
 
devbyrayray profile image
Dev By RayRay

Yes, most of the time I use toPromise() 😉

Collapse
 
nombrekeff profile image
Keff

I really liked the format and art of the article!

I tend to use observables as they are more powerfull than promises, with al the rxjs utilities. But I use them mostly for HTTP requests and such. Though I agree there are some cases as you point out, where promises should be prefered.

Collapse
 
devbyrayray profile image
Dev By RayRay

Yeah, Observables are very powerful! They offer a great variety of tools to build reactive interfaces. But we should pick the best tool for the job, right 😉

Collapse
 
nombrekeff profile image
Keff

That's it, picking the right tool for the job. you wouldn't use a toothbrush to clean the house right? :P

Thread Thread
 
devbyrayray profile image
Dev By RayRay

🤣🤣🤣🤣 would be a great accomplishment! But yeah true!

Collapse
 
jdgamble555 profile image
Jonathan Gamble

According to this post, because Observables are faster.

Collapse
 
devbyrayray profile image
Dev By RayRay • Edited

When I read the post, I can't find actual evidence in what way Observables are faster.

A person on StackOverflow has run a great test to measure the performance of a Promise and Observable. There you can see that a Promise is more performant than an Observable.

But that's not the only point of the Promise vs. Observable debate. Just pick the right tool for the job.

I found this great list on StackOverflow on when to use one over the other; maybe it's helpful to you.


Use Promise instead of an Observable, when:

  • You need to handle the (future response) event no matter what (no unsubscribe, no cancel: after you subscribe, there will be an answer, 100%, and you will have to handle it, 100%, the code will get executed)
  • One SubscriptionSubscription = One Event handling: there will be only one event from the source, so the future response and the completition is the same event.

Use Observable instead of a Promise, when:

  • You want to have the ability to accept multiple events from the same source
  • You need a "I am finished with this event stream" handler
  • You want to be able to unsubscribe from a possibly never ending stream of data, and re-subscribe anytime (meaning also that you might don't really need to fulfill the SubscriptionSubscription at all: for instance, if nothing happens in 10 sec, let's unsubscribe, nobody will ever handle the late answer)
  • You want to use the RxJS "Stream API" to preprocess the data of your responses.
  • Generally, the Observable pattern is an extended Promise pattern, with a lot more tools and functionality. It is up to you to decide to limit the code with Promises or not. It was first a custom libary, then got included in ES2016.

Source: StackOverflow

Collapse
 
athomsfere profile image
Austin French

The test right under that, which to me reads as a better test anyway: Observable wins.

Collapse
 
jdgamble555 profile image
Jonathan Gamble

Everything seems to be in Observables in Angular, so after a little experience, you get good at going between the two for your needs. I think it helps you master async techniques in general. I tend to use .pipe(take(1)).toPromise(); all the time, but never go from Promise to Observable. As you said, they have different uses, depending on the data source.

Collapse
 
bwca profile image
Volodymyr Yepishev

Well, technically Observable from http request is finite if I recall correctly, so in most cases you can disregard unsubscribe. But yeah, no need to be fixed on Observables alone 🤓

Collapse
 
devbyrayray profile image
Dev By RayRay

True, that's the beauty of an Observable. You can unsubscribe to it! 👍