0

I just setup routes in my angular app. The first view, List makes an http call to get a list of presentations

function ListController($scope, $http)
{
    $scope.error            = null;
    $scope.presentations    = null;
    $scope.requesting       = true;
    $scope.currentTitle     = '-1';
    $data = {
        'type' : 'presentations'
    };

    $http.post('resources/request.php', $data, {timeout:20000})
        .success(function(data, status, headers, config)
        {
            $scope.requesting   = false;
            $scope.presentations    = data;
        })
        .error(function(data, status, headers, config)
        {
            $scope.requesting   = false;
            log(status + ', data:" ' + data + '"');
        }
      }
    );
}

My route is

angular.module('main',[]).
  config(function($routeProvider) {
    $routeProvider.
      when('/', {controller:ListController, templateUrl:'resources/views/list.html'}).
      when('/view/:id', {controller:VforumController, templateUrl:'resources/views/vforum.html'}).
      otherwise({redirectTo:'/'});
  });

the problem I have is when I go to #/view/:id and then back to / the $http call gets called again. How can I make it so it only loads the first time going into the app and reference the same data that was loaded the first time?

I attempted to create a variable outside of angular and set it equal to the data loaded the first time. Then, in the ListController basically did a if data is null, do the $http call else set $scope.data = data but that didn't work. The list view was just blank. $scope.data is what builds my list.

2
  • Did you try passing $route to your controller and checking the $routeParams before the $http.post()? Worth a shot. Commented Mar 22, 2013 at 22:20
  • I've never used $routeParams before..well, $routes in general. This is my first time. I'll look into this, thanks Commented Mar 22, 2013 at 22:26

1 Answer 1

4

What you want is a service, which in angular is a singleton:

.factory( 'myDataService', function ( $http ) {
  var promise;

  return function ( $data ) {
    if ( ! angular.isDefined( promise ) ) {
      promise = $http.post('resources/request.php', $data, {timeout:20000});
    }

    return promise;
  }
});

And now you can simply replace the call to $http with a call to your service:

function ListController( $scope, myDataService )
{
  // ...

  myDataService( $data ).then( function success( response ) {
    $scope.requesting = false;
    $scope.presentations = response.data;
  }, function error( response ) {
    $scope.requesting = false;
    log(status + ', data:" ' + response.data + '"');
  });
}
Sign up to request clarification or add additional context in comments.

5 Comments

I don't think I am doing this correct. I am getting $data is not defined. Again, haven't used factories/services before: pastie.org/7084834 what is wrong here? How do I pass $data to the service?
That depends on whether it's static. Since you defined it statically here, you can just place it statically in the service. If you want to have it dynamic, then your factory can return a function instead. I'll update the answer for the latter case.
Awesome, that worked! Is var promise what the service is checking? I am not sure what is making it so the app doesn't invoke the $http call twice. In other words, does promise containt my loaded data?
No, promise is a promise. :-) A promise provides an API for working with data that is generated asynchronously. $http returns one, which we store the first time the function returned from the service is called. Each subsequent time, that promise has already been defined, so we just return the existing one. Inside the promise chain is your data; you must always access the data from within then blocks because your code doesn't know if the data has been loaded yet. Whether it takes 7 ms or 7 sec won't matter and you don't need to account for it.
Ok, I understand now. This is awesome. I am loving angular the more I use it, thank you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.