Observables are mentioned briefly in my Angular Concepts post but I wanted to dive a little deeper into this concept. Along the way to using observables in http are the concepts of asynchronous programming, ajax, and promises.
async await to help developer use the code in a synchronous wayJavascript takes advantage of using asynchronous programming when making http requests. Most programming that we're used to when coming from backgrounds of C++ and Python is synchronous, meaning one task must be completed before another task can begin. This is good for procedural code that relies on the logic of previous statements. However, when using the browser and HTTP requests, forcing the rest of the app to wait for an http call to complete can be bad for performance, making for a bad overall user experience. Asynchronous Programming will allow for other code to still run while your http calls may still be completing.
When I first learned to make http calls in JavaScript in 2011, a technique called AJAX (asynchronous javascript and xml) was used to get data via an http call. The advantage of using AJAX was that you could still have code on the page to let the user know that something was happening, like a spinner. The call would also be made without the page needing to be refreshed. This was huge because you could start using a click event on a button to submit a form and get data back in real time without going the traditional route of using a submit element on a form.

This worked very well with jQuery, an extremely popular framework of javascript. It also confused me a lot because it was not was I was used to coming from C++ and Python. In the following code, I would expect the http call to either succeed or fail and then run the code after.

Notice that the success and error options define a function. JavaScript will allow the user to define a function on the spot without giving it a name because they are known as anonymous functions. Specifically, when these anonymous functions are defined on the success and/or error options of an ajax call, they are known as callback functions.
Instead you can see that "This text runs after" is logged to the console before any success or failure from the ajax call. It's contrary to what you might think but can be useful in the case where the http call times out because you can still have code run. The obvious option here might be to define all of the code that you want to run after the call returns inside of your callback functions. You can even call other functions inside of those functions.
This type of code quickly became very difficult for other developers (and yourself two weeks later) to follow and became known as callback hell. The name is quite indicative of the type of torture that it would cause.
Gradually, frontend development has shifted from using jQuery to using dedicated frontend frameworks such as Angular, React, and Vue. Angular, my personal frontend framework, makes use of observables.
Observables are part of a larger package bundled with Angular called RxJS and are used frequently with the HttpClientModule of JavaScript. When following an Angular tutorial, you'll often see code to request a resource written like this.
This method getPost() will return an observable. Because of Angular's use of typescript, you can see this very easily when we properly type everything.
The concept of interfaces is beyond the scope of this article but it basically just defines the objects that are to be returned in the observable.
When learning to use the HttpClientModule, you probably found out that you cannot just call the method like the following.
That code does not work because the HttpClientModule makes use of asynchronous programming to return an observable. An observable can be thought of as an open data stream. Observables offer very powerful method such as .subscribe() and .unsubscribe(). The code that you would actually use the get the post would be like the following:
Basically, you're subscribing to this observable and setting the post on the component (this.post) to the value of the returned post. You will also handle errors in a more elegant way by simply defining the second argument for the subscribe.
The .unsubscribe() method of observables is very nice because it will allow you to cancel an HTTP request. Let's say for example that you'd like to create a button that will close your observable so that it no longer queries the server.
There is still one glaring issue with observables that may not be clear on first glance: How do we avoid callback hell? Again users might be tempted to stuff the rest of their code into the subscribe() method, but this will quickly make unreadable code for yourself again. If you have code such as the following, this code should run last will still be output before anything else in the subscription.
Observables build on top of a previous JavaScript technique called promises. Promises were a feature added to JavaScript as an attempt to, in addition to having more elegant and readable syntax, avoid becoming engulfed in callback hell. Furthermore, developers saw an easier way to work with asynchronous code in ECMAscript 2017 with the introduction of async await. async await is an easy way to define a function with the async keyword and tell it to wait for any promise to complete with await before proceeding with anymore code. From its inception, RxJS sought to make observables and promises very interoperable. This means that any observable can be converted to a promise with the .toPromise() function.
Making use of toPromise() and async await, we can redefine the method that makes the HTTP call to return a promise instead.
Now, the component ngOnInit can be defined with the async keyword. Since we're not using a promise, we simply have to change the .subscribe() function to .then(). As you can see, .then() takes the same arguments, but now that we're using a promise, we're able to use await to ensure that the promise completes before this code should run last is output to the console.