Kotanet
Kotanet

Reputation: 573

Call factory only on first load

I have this code inside my controller:

$scope.customers = [];
$scope.categories = [];

function init() {
   partnersFactory.getPartners(categoryId)
   .then(function(res){
      $scope.partners = res;
   },function(status){
      //err
   })

   partnersFactory.getCategories()
   .then(function(res){
      $scope.categories = res;
   },function(status){
      //err
   })
}

What I do need, is to run partnersFactory.getCategories() only once on initial load, and then save it unchanged. What is the best approach to do it so? Using some variables like var initialization = false look not very clean.

EDIT The purpose: I have some data sorted by categories. What am I doing now: if someone clicks on category, I reload the dataset from server, but filter it to the category (server-side). That's why i need to reload data, but not the categories. Am I doing wrong? Maybe it's better to filter it inside angularjs?? (the data on server is not constantly updating).

Upvotes: 1

Views: 2320

Answers (4)

Artyom Pranovich
Artyom Pranovich

Reputation: 6962

In your factory you can do it smth like this:

.factory('partnersFactory', function($http) {
    var categories = [];

    var getCategories = function() {
       $http.get(...)
          .success(function(data){
             categories = data;
          });
    }
    getCategories();

    return {
        getPartners: function(categoryId) {
           $http.get(...)
              .success(onSuccess)
              .error(onError);
        },
        getCategories: function(){
           return categories;
        }
    };

It should cash categories data.

Upvotes: 1

tanou
tanou

Reputation: 1093

So, what you need is something like that:

in your controller, create 2 methods, one for getting the categories, the other for getting the data:

angular.module('yourApp').controller('yourCtrl', ['$scope', 'yourFactory', function ($scope, yourFactory) {

  $scope.initPage = function () {
     $scope.getCat();
     $scope.getData();
  }

  $scope.getCat = function () {
     ...
  }

  $scope.getData = function () {
     ...
  }


  $scope.initPage();
}]);

then in your html, on the button/element supposed to reload data, call your method with a ng-click

<div>
  <button ng-click="getData"> reload </button>
</div>

As you want to sort per categories, you can do something like adding a param to getData(category) to precise by which category you want to filter your data, then in your html

<ul>
  <li ng-repeat="cat in categories"> <a ng-click="getData(cat)"> {{ cat.name }} </a> </li>
</ul>

hope it help

Upvotes: 1

Kalhan.Toress
Kalhan.Toress

Reputation: 21901

putting partnersFactory.getCategories() out side of the init() function will only execute one time

so your controller likes to be,

$scope.customers = [];
$scope.categories = [];

function init() {
   partnersFactory.getPartners(categoryId)
   .then(function(res){
      $scope.partners = res;
   },function(status){
      //err
   })       
}

partnersFactory.getCategories()
.then(function(res){
    $scope.categories = res;
},function(status){
      //err
})

and if you need a clean copy of the $scope.categories use angular.copy() like below

partnersFactory.getCategories()
.then(function(res){
    $scope.categories = res;
    $scope.originalObj = angular.copy($scope.categories); // don't do any changes to $scope.originalObj
},function(status){
      //err
})

Upvotes: 1

ValentinH
ValentinH

Reputation: 948

What about:

$scope.customers = [];
$scope.categories = null;

function init() {
   partnersFactory.getPartners(categoryId)
   .then(function(res){
      $scope.partners = res;
   },function(status){
  //err
   })

   if($scope.categories == null) {
       partnersFactory.getCategories()
       .then(function(res){
          $scope.categories = res;
       },function(status){
          $scope.categories = [];
       })
    }
}

Upvotes: 1

Related Questions