Angular RxJS unsubscribe as a feature design

After few hours of thinking and more hours of implementation, I finally proved my idea is workable. I found it be a bit intriguing and so let me share it. Before jumping to the matter at hand, I would like to briefly mention that:

  • I don’t believe in end-2-end testing
  • I prefer unit testing
  • I like to test-drive my code

A few more details can be found here. On top of the above, I dislike using mocks, spies, stubs and other fakes to make testing “easier”. Now don’t get me wrong I do use mocks a bit, but mostly at a boundary (calls to backend, db and such). Let’s be reasonable, if code is a mess and/or legacy or there is a time constraint, options tend to dwindle and if you have to mock, you mock.

Now let’s see about my situation: I have simple app with navigation bar, located at the very top of the screen and top of the component hierarchy. The navigation bar contains search component. Below I have the main space with a router that happily swaps out different main components, depending where you click.

There is no simple way to pass data from the search component to presently displaying main component, unless we use observable, in particular Subject observable. So we have search observable and a main component is subscribed to it. The question is: “how do we test unsubscribe in the main component when we navigate away and the main component is destroyed?”.

After some thinking, I realized that NOT every main component is searchable, in those cases search component can be hidden. The approach has elegance to it, since it will help with testing and at the same time enhance user experience by eliminating confusing search feature that doesn’t seem to do anything when non-searchable main component is displayed.

On the other hand, when main component is searchable, then search component must be displayed so user can search it.

Ok, so how do we go about killing two rabbits with one bullet? We will enhance the search observable so it will count how many subscribers it has. Whenever any main component subscribes or unsubscribes to the search observable, the count will go up or down. Next a bit of elbow grease to wire up search component to hide/show when the count is equals to or less than 1 and we are done.

The whole logic can be tested by checking if the search component is displayed or hidden via jasmine spec, by navigating between main searchable components and main non-searchable components. No mocks, no spies, just elegant, user friendly feature and code design.