As a company that has a specializes in migrations, we understand the frustrations when it comes to the migration from AngularJS to Angular, especially when issues arise due to differences between Promises in AngularS and Observables in Angular2+.
In this article, we would like to highlight the key differences between Promises and Observables and clear confusions that you may have.
Promises are commonly used in AngularJS to handle HTTP requests. After making a request, a single response is expected with which the promise is resolved as in the example below:
However, resolving a Promise again with a different value will not work. It is always resolved with the initial value passed to the resolve function and disregards next calls to it:
In contrast to Promises, Observables emit a stream of one or multiple values that are all passed to their subscribers as illustrated in the example below. Typically, the Angular HTTP service provides an Observable stream with one response value, making its behaviour alike to a Promise.
In basic migration scenarios, the AngularJS $http service can be replaced by the Angular httpService. However, if you are dealing with more complex applications there a many key differences to pay attention to. Hereafter, we will discuss the most common differences:
Eager vs. Lazy
In the example above, when you call the saveChanges method, the initial Promise-wrapped request will function. While Promises are eager-evaluated, Observable-wrapped requests will not do anything as Observables are lazy-evaluated.
Observables will be called only if you subscribe to them. In the previous case, the post Observable needs to be subscribed as follows for the http called to be executed:
Let us have an example where on input text change from the user a search is requested on the backend. One major disadvantage is that you cannot reject the results of the initial request if you keep typing. Although you can ease this problem with a debounce, it does not entirely resolve the problem. Further on, there is a possibility of race conditions, which means that an incorrect response will be displayed due to the later request result coming back before earlier requests.
An Observable eliminates this issue elegantly with the use of the switchMap operator:
In this example, the input text typing is converted to an observable value stream. Each time a new text value is being emitted, the switchMap operator will cancel the last network requests and send a new one, if the last one is not finished.
Implementing a retry logic with Promises is a complex exercise that typically ends in a variation of the following code:
However, with Observables the same retry logic is implemented with the following one-liner!
Promises only have two combination tools:
In contrast, Observables have a variety of combinations:
To conclude, when you migrate from AngularJS that uses Promises for HTTP calls to Angular2+ that uses Observables, you need to be careful about the differences between the two frameworks. In particular, Observables offer powerful combination tools that should be leveraged to simplify the codebase.
We hope that this article was helpful to you and clarified differences that will ease your future developments or migration!
Hope you enjoyed today's #MondayBlog about Observable best practices. For more content, follow us on LinkedIn and subscribe to the newsletter on our website, and we will make sure that you’ll not miss out on anything! Have a great and productive week and see you at the next #MondayBlog by LogicFlow!
Checkout our job postings on the career page. Or contact us at [email protected].