Sharing Broadcast Messages between Angular 1 & 2

I'm in the middle of migrating a project from Angular 1 to Angular 2. Every now and then I hit a bump in the road where architecture/design decisions in the Angular 1 version don't always have a clear path into the best practices of Angular 2.

I ran into one of those instances recently when implementing an HTTP Interceptor.

The Problem

The Angular 1 code relied on $rootScope.$broadcast in order to tell other parts of the app when an HTTP call responded with a server error. (This mechanism will be changed once all of its players are migrated to Angular 2)

Unfortunately, there is no built in way to send a broadcast from an Angular 2 service to the Angular 1 $rootScope.$broadcast mechanism.

The Solution

At this point, it is either refactor the Angular 1 code to decouple the broadcast handlers from the components they live in (not a bad idea, since it'll have to happen during the migration anyways), or figure out a way to pass broadcasts between the two versions.

I opted for the latter since there are other places in the app that will need broadcasts all the way up until I'm fully migrated.

Caleb Williams and I were chewing on this challenge in the breakroom one day and this is the result!

First, we create a service that Angular 1 and 2 can both use to send each other broadcast messages.

This service has two public Subjects. One is for broadcasts coming from Angular 2 ( ng2Broadcasts ), and the other is for broadcasts coming from Angular 1 ( ng1Broadcasts ). It also has two convenience functions for updating each Subject.

The intent here is that each version's interested parties can subscribe to the broadcasts coming from the other version.

In my case, I want to just relay all broadcasts coming from Angular 2 straight onto $rootScope.$broadcast.

So we downgrade the BroadcastInterfaceService and do just that.

Then, in Angular 2 when you need to send a broadcast to Angular 1, you import BroadcastInterfaceService and call .sendToNg1().

Likewise, in Angular 1 code, we'd inject broadcastInterface and call .sendToNg2(). Unfortunately, there is no way to listen to all Angular 1 $broadcasts and relay them. Any interested party in Angular 2 needs to subscribe to the ng1Broadcasts Subject and listen for a specific message.

Final Thoughts

Broadcasts aren't really "a thing" in Angular 2 since everything is moving towards RxJs Observables, but during a migration it may not be possible to completely discard them. This is one way to bridge the gap in the interim.

comments powered by Disqus