3

In my AngularJS app's signup process, I'm constantly updating a user object.

This may be the wrong way to do it, but I'm using one "signup" controller for all of these signup steps (as the logic in the steps is all very similar and it makes for neater code rather than making a separate "signup1", "signup2" etc controller for each view.

I have a promise that returns userInfo from my database:

.service('userInfo', function ($http, $cookies) {
      var userId = $cookies.id;
      console.log("UI Cookies", $cookies);

    var promise = $http.get('/api/findProfile/' + userId, { cache: false}).
      success(function (data) {
          var userInfo = data;
          console.log("This is fresh data!") // This logs the first time I load my page, but never again
          return userInfo;
      }).error(function(data) {
          console.log("ERROR")
          return userInfo
      });
      return promise; 

})

When going from one signup step to the next, I update the profile info on MongoDB then load the next page. If I load the page via changing $location('') from my controller, I get old userInfo that hasn't been updated in my database. However, if I do a full page refresh I get the correct, updated userInfo.

Is this a caching issue? I've tried passing {cache: false} to my $http promise but I'm not getting fresh data (as denoted by the console.log("This is fresh data!"); rather, I'm getting cached data back.

How can I resolve this beyond forcing a full-page reload in Angular?

JVG
  • 20,198
  • 47
  • 132
  • 210

1 Answers1

4

This is not a caching issue, or at least not the way you think.

Services and factories are singletons in angular, meaning that they get initialized once, before they are first requested to be injected. After that, the service function will not run, all controllers will receive the same object. (In case of a service, the injected object is created by using the service function as a constructor)

If you want to poll for some data every time a view is loaded, you have to initialize the request in a controller (you might do this via a service regardless) - which does get re-initialized without reloading the browser page.


Also, you seem to have some issues with using promises and return values. There's no point in returning from the error and success handlers, as their return value will be discarded. See this discussion for more information on "returning" from async functions.

It's probably easiest if you just return the $http promise from a function in the service, then every controller can handle the promise appropriately, ultimately reducing your service code to this:

.service('userInfo', function ($http, $cookies) {
  var userId = $cookies.id;
  console.log("UI Cookies", $cookies);

  //this function returns the promise returned by $http.get  
  this.getData = function(){
       return $http.get('/api/findProfile/' + userId, { cache: false});
  };
})
Community
  • 1
  • 1
doldt
  • 4,466
  • 3
  • 21
  • 36
  • Ah, that makes sense, I figured this would come down to me not understanding how services actually work! So would you suggest just loading in the `$http.get()` call into my controller so it's a fresh set of data every time? – JVG Aug 05 '15 at 07:54
  • Scratch that, you've updated it in your answer. Cheers mate, got it! – JVG Aug 05 '15 at 07:54
  • @Jascination both approaches are viable, if you want to possibly reuse this http request in other controllers too, it's better to move it into a service (probably also better from a testability point of view). You can create a function in the service which returns a fresh promise every time it's called. – doldt Aug 05 '15 at 07:58
  • Alternatively, let the service provide a function that returns fresh promises – Bergi Aug 05 '15 at 08:00