Loader/spinner?

I think this is an issue where reasonable people can take different logically defensible positions. Mine is that providers should stay away from UI/view layer concerns completely. The components/pages should be the only entities popping loading indicators. A concrete example: a provider doesn’t (and shouldn’t) know about the context in which it’s being invoked. Say we have a periodic task that updates information in the background, in addition to an explicit user-driven refresh button. When the user presses refresh, a loading indicator is appropriate to show that the app is being responsive. When it’s being done in the background, the loading indicator will be disruptive and annoying. If the service is in charge, it can’t tell the difference. Yes, then you can add booleans telling the service whether to pop the loading indicator, but at that point I think the whole design is more complex with no real benefit over doing it all in components. If it were dozens of lines of code needed to manage a loader, the case for centralizing control would be stronger, but as it is with it just being a few, I think the downside of lack of flexibility and blurring the lines between the various app layers makes this style less readable than following the rule that only view layer components can do view layer things. Again, to reiterate, this isn’t a really strongly held opinion and I don’t make any claim that it’s absolute truth, but it’s where I am on this matter at this point.

1 Like

I’ve actually created methods in the database service like getInformation() and getInformationNoSpinner(). The first method sets up the spinner and calls the second method. Then the app can call either, as desired. This is probably “the same” as the use of boolean flags you mention.

I decided to put the spinners in the service because of concerns about error-trapping and Promises swallowing errors. It seems as though I have to include the catch block right away (i.e., in the service) and I need to dismiss the spinner in the catch block.

I see your point about separating by layer. I haven’t explored any Promise libraries, but I wonder if Javascript has weaknesses that fight against your concept. Question: in order to implement that layer approach most correctly, would I need to use 100% Observables, no promises, so errors would stay handle-able across layers?

I don’t believe so. Looking at the unit tests, Observable.toPromise() does what it’s supposed to in terms of errors. Now if you are explicitly instantiating Promises using the infamous boilerplate code that doesn’t pass errors through properly, yes I could see problems. But if you stick to toPromise(), everything should be fine.

I plead the Fifth!

Thanks for the comment. I actually just started using toPromise about a week ago. Too bad it took me so long to get there, but I appreciate your perspective.

Another situation that is problematic with putting the loading controller responsibility in services, that I don’t think even your two entry point design can address:

Some user action causes three network requests to fire. You want the loading indicator to be visible until they have all resolved. There isn’t really any way to predict which is going to finish when, so if you only call “loadWithSpinner()” on a random one, the timing might be off. If you call it on all of them, you have three layered flickering spinners which looks confusing. On the other hand, this is really simple if controllers are responsible for managing spinners, because they can use forkJoin or Promise.all to decide when to dismiss.

1 Like

Couldn’t that become a logic issue for the DOM layer also? I hear your comment as an argument for creation of a SpinnerManagementService, whose job is to accept multicasts of streams requesting a spinner, and to gracefully display and dismiss spinners as appropriate. This interests me enough that I might build it, but maybe I’m being excessively “principled.” If the logic were centralized in a service, then no one page would need to know about every request.

I guess again this is somewhere where reasonable people can disagree. When I see something visual, I know that a view layer entity (a page or component) is responsible. When it is three or four lines of code to deal with these things, I just feel that something like a SpinnerManagementService looks like a solution in search of a problem.