catdadcode / angular-spinners

A library for easily managing loading spinners in complex Angular2+ applications.
MIT License
140 stars 49 forks source link

Need help with onLoaded #21

Closed Tyree closed 8 years ago

Tyree commented 8 years ago

I'll admit I'm an angular noob and some of the concepts yet escape me, but I am having a hard time figuring out how onLoaded is useful to me.

Example: I have a sign up form where I would like to show a spinner while the addUser() operation is running. I am calling spinnerService.show('signUpSpinner'); in the beginning of the addUser() function and then hiding it at the end. Simple enough. But I am getting the 'Error: No spinner named 'signUpSpinner' is registered.'.

So, I get that I'm supposed to use onLoaded when I place the spinner element in the html, but how do I then utilize the show/hide inside the addUser() function? The example for onLoaded shows the show/hide ops inside of a function that seems to be specific to spinners. I don't want to run the addUser() function when the spinner is loaded, so I know I have to have some intermediate function that fires when the spinner is loaded, but what does that do for me when utilizing it inside another function? I can have another function that fires when the spinner is loaded, but I'll still have the same problem when I call it from addUser().

Is there a better way to put the spinner in the html so that I don't always get the 'No spinner registered' error? The way I'm using it now seems like the way I would always use it. So there has to be a better way to avoid using onLoaded in every case.

Sorry. I know this is probably an eye-roller question. I'm picking it up as fast as I can. :-D

Thanks! Matt

catdadcode commented 8 years ago

The function you're referring to is not specific to the spinner library. It was an example of a user function.

<spinner name="mySpinner" on-loaded="spinnerLoaded(spinnerApi);"></spinner>
app.controller('myController', function ($scope) {
  $scope.spinnerLoaded = function (mySpinner) {
    // Now you can do:
    //   mySpinner.show();
    //   mySpinner.hide();
  };
});

In your controller you can setup a function on $scope. This is no different than setting up a function for an ng-click or something in your app, but instead you supply the function to the on-loaded property on your spinner directive. When Angular finally gets around to parsing the spinner directive and the spinner finishes registering itself with the spinner service then it will execute the expression you passed to on-loaded. At that point you can either use the injected spinnerService in your controller like this:

app.controller('myController', function ($scope, spinnerService) {
  $scope.spinnerLoaded = function () {
    // Now you can do:
    //   spinnerService.show('mySpinner');
    //   spinnerService.hide('mySpinner');
  };
});

Or, the spinner directive also makes that specific spinner's API available to your expression and you can pass it in like in the first example and interact with just that spinner directly. Either way works fine.

Bottom line is that the onLoaded expression is there so it can fire off some logic in your app after it's finally registered with the spinner service. This happens simply because of the order Angular does things and you end up calling spinnerService.show before the spinner directive was parsed.

If all you need is to simply show the spinner right away, there is another trick. You can set show="true" on the directive and it will show itself even before it has registered with the service. In many cases the spinner is registered by the time you need to call spinnerService.hide.