3

I'm using angular-seed template (AngularJS) and I have routeProvider setup and such, now I want to execute a function (which resides in a factory), but only the very first time when the page gets loaded. I found many solutions for this, but I don't want to execute the code each time the users switches between tabs (via routeProvider of course, page doesn't get reloaded) - the code must be executed only when the whole page gets (re)loaded.

How should I approach this? I tried to call the function from run and then broadcast the event when page gets loaded, but there are no event listeners - I guess that is because the run part gets executed before the controllers are setup, so there are no listeners attached at the time when the event gets broadcast.

So, any suggestions how to approach this?

UPDATE

Use case:

  • when user types the url in the page, the page gets loaded
  • when pages gets loaded, a $http.get request is performed, which gets a random content
  • this content can be changed only by clicking a button, to explicitly request a change of content.
  • if users clicks to a different page e.g. view2 (routeProvider) and then back to the view1, the content must not change
  • when users refreshes the page (F5), the content changes again (or as already stated, by a click of a button)
Fedearne
  • 7,049
  • 4
  • 27
  • 31
uglycode
  • 3,022
  • 6
  • 29
  • 55

1 Answers1

3

Use the run method:

app.run(function(yourService){
  yourService.cacheRandomContent();
});

It runs only once after the app is bootstrapped and services are created.

To access the data in controller, just inject the same service:

app.controller('someCtrl',function($scope, yourService){
  yourService.getCachedRandomContent().then(function(resp){
    $scope.data = resp.data;
  });
});

Your service would be something like:

app.service('yourService',function($http){
  var promise;
  return {
   cacheRandomContent: function(){
     promise = $http.get();
   },
   getCachedRandomContent : function(){
       return promise;
   }
  }
});
T J
  • 42,762
  • 13
  • 83
  • 138
  • I tried that, but how do I send the data from `factory` to a `controller` where I actually display the initial data? – uglycode May 27 '16 at 12:02
  • @uglycode Can't you inject this service in the controller and access the data? This does exactly what you asked. Maybe you want to provide more details. – T J May 27 '16 at 12:04
  • I've provided a use case for what I'd like, refresh my initial question – uglycode May 27 '16 at 12:08
  • @uglycode can you check the update in answer and explain why you can't do that? – T J May 27 '16 at 12:09
  • OK I'll try to implement this, but in the meanwhile, what if `yourService.someMethod();` in the `app.run` takes like, a long time, and `controller` gets initialized before? Then the `getData` inside the `controller` would return null, wouldn't it? – uglycode May 27 '16 at 12:11
  • Could you please update your answer a provide a bit more information about how the service should be implemented? I thought that `someMethod()` calls the `$http.get` and stores the values locally in a variable inside the service, whereas `getData()` returns that variable, but this is surely not right... – uglycode May 27 '16 at 12:18
  • @uglycode Added a tiniest version of service you'll need. BTW you don't need the run method for this, you can add logic in your service to make the request only if it wasn't made earlier – T J May 27 '16 at 12:21
  • Nice! Haven't even thought of that, now it all makes absolute sense. Thanks! – uglycode May 27 '16 at 12:24