Angular View Updating Using Observables, Behavior Subject, and Event Emitters

Tristan Holaday
6 min readMar 23, 2020

Angular has an awesome built-in feature for updating views dynamically known as Change Detection. Essentially, when an event occurs, change detection is triggered and the new data gets displayed, which allows for a superior user experience, and honestly just looks cool 😀! This article is less about the inner workings of change detection and more focused on a very specific implementation of change detection. If you’d like to know more about how it all works, I recommend checking out the following:

There are different types of events or objects that trigger change detection in Angular. We’ll be looking at, as you already know from the title, Observables, Behavior Subjects and Event Emitters, but more specifically how to use them when fetching/sending data within related and unrelated components.

Related Components: Observables + Event Emitters

Ok let’s set the scene…queue the soft jazz and dim the lights…

Let’s imagine we’re fetching data from a database on the initialization of a component. To fetch the data, we’re using a service that defines an observable, to which we subscribe to get the data for our view.

At this point it’s tempting to believe that our work is done (wow we’re fast!) that now when new data is sent to the DB our observable will detect it and update our view accordingly.👏

Sadly that is not the case 😥. The reason being is that our observable is “pointed” to an http request, which by design closes as soon as it delivers its response, and thus, unless the observable is explicitly told to fire off another http request, it will never know the database has been updated.

One way around this is to use websockets. However, let’s assume that’s not an option because your manager forbids it because he/she thinks of little tiny sock puppets singing about the internet every time they hear the word, and it terrifies them…. (web sockettes 😅)…ok… well that’s no biggie. We can just push the new data into the collection from the frontend, along with sending it to the DB, once the user submits the form. Remember, submitting a form is an event and, if in that event we update the collection, change detection is triggered and the view updated with the new information. Sweet, we’ve solved it! But wait, this will only work if said form exists in the template of the component. What if the form is in a child component, say in a modal? Oh shoot. No worries! This is when event emitters come into play.

Pics first!

Ok, so in the template of our example companies component we have two modals that we’re “injecting” into the template. These are going to be our forms for creating or updating data. Notice that in <creation-modal> we have an event, (addedData), and in <update-modal> it is (updated). Those events are tied to the child components, the modals, in this way:

So we’ve defined in our modal components these EventEmitters(). Now how do we trigger them?

So the event emitters are fired off when we call “emit” on them. In this case, I’m passing the callback data with emit().

If you happen to recall, earlier we defined (addedData) and (updated) in our parent template and they triggered methods in the parent component, passing off the data from the “$event”. ( i.e. (addedData)=”addData($event)” ). What follows is this:

So our functions in the companies component are called from the template with the given callback data, which is either added to the collection (in this scenario an array) or used to update the values of an object in the collection. And because an event occurs, our view updates and our users are happy. Yay!!!

Unrelated Components: Observables + Behavior Subjects

The question now is what to do if your form isn’t in a child component but in a completely separate component. For this situation we can’t use the standard event emitters but we can do something similar by using Observables and Behavior Subjects — or I guess technically a behavior subject as an observable 🧐.

How is this going to work? This is how I like to think of it:

We have two components and a service. Both components connect to the behavior subject service, which is going to pass the new data from the form component to the list component.

So let’s first define a data service with a behavior subject and a method that calls “next” on the subject.

*Note: data: object = {} is an empty object with which we’re using to “initialize” the behavior subject. It allows us to check for null before performing any action in whatever component subscribes to the currentData observable.

Notice how we define an observable based off the behavior subject. We’re going to subscribe to that observable in our list component. The changeDataSub() method is going to be called from the form component as such:

So when the form is submitted, the callback data is added to our behavior subject, which we’re subscribed to like so from the list component:

*Note: this requires you to make a dataSubject object in the component (i.e. dataSubject: any = {}; )

Eureka! Now when new data is sent to the DB it is also passed between unrelated components via a service, and… because we’re subscribed to an observable, change detection is triggered and the updated list is updated in the view as well. 😎

Observables, behavior subjects, and event emitters are wonderful tools for creating more sophisticated and enjoyable views. This is just a look at two specific use cases for how to implement them. If you’re unfamiliar with the details of these Angular features, there are lots of great articles out there that can describe them and their properties in far greater depth than I can. It’s worth looking further into them.

If you have any questions or constructive feedback, please let me know. 🙂

Cheers!

--

--