Dismiss
Announcing Stack Overflow Documentation

We started with Q&A. Technical documentation is next, and we need your help.

Whether you're a beginner or an experienced developer, you can contribute.

Sign up and start helping → Learn more about Documentation →

I think my stackoverflow search-fu is broken today, because it can't be that I'm the only one who's ever asked this. Cripes, I hope not, because I could really use some help figuring this out. Switching between data-sources is the big part, but 'best way to abstract' is the logical next-question on this, too.

Anyway: I have something like three dozen widgets. Each widget has one of three data sources (API-full, API-short, json file). I'll have users just coming in from the intarnets, users with a sales-provided temporary login, and users who've logged in with their own API key.

  1. no login = dummy data/json
  2. temp login = data from abridged endpoint
  3. API key = full data set endpoint

Logicking this out, I'll have $scope.access for user access + $scope.widget for which widget the user clicked. Falling back on old functional habits, it seems like I could use those two in a case break, and return a value for the appropriate endpoint. But I can't seem to get a variable to work the $http call, like this:

$http.get($scope.call).success(function(data) {
    $scope.group = data;
});

So my question boils down to:

What's the best way (or can I) re-use an $http with a variable, so I can just insert the variable and not have to do a separate $http for every combination?

How should I (or should I) abstract this logic and get this out of my controller?

What would be really excellent is just something I could call in my controller, maybe like so:

var X = getEndpoint($scope.access, $scope.widget);
var Y = getEndpoint($scope.access, $scope.widget);
var Z = getEndpoint($scope.access, $scope.widget);

and the rest be hidden under the hood elsewhere. Any ideas on how to tackle this?

Many thanks in advance.

share|improve this question
    
May be separate the logic out into a service? – runTarm Aug 10 '14 at 18:16
    
...and then call the service where I just input the two variables and get back something? That gets it all out of the controller, but would I still have to do the endpoint logic longhand? I was just hoping there'd be a more efficient way. – kl02 Aug 10 '14 at 19:55
    
Then may be consider using $http's Interceptors. – runTarm Aug 10 '14 at 19:58
    
googling now. thanks! – kl02 Aug 10 '14 at 20:03
up vote 0 down vote accepted

As @runTarm stated in his/her comment, you could wrap you API calls' logic inside separate service. And yes, you could use interceptors to control your http calls.

One of many options is that you store your API endpoints for each user type somewhere (e.g. in angular constants) and then use the one that matches the user's access right level inside you service. All your controller/widgets could use the same service which holds logic to determine the endpoint.

I know I'm simplifying things here, but consider a service getting data over http based on access level:

app.factory('MyService', function($http, API){
  return {
      get: function(accessLevel) {
        var endPoint = (_.findWhere(API, { access: accessLevel })).endPoint;
        return $http.get(endPoint);
      }
   }
});

This would get data from endpoint determined by given access level. Here API is a constant:

app.constant('API', [{ 
    access: 1, 
    endPoint: 'http://jsonplaceholder.typicode.com/posts'
  },{ 
    access: 2, 
    endPoint: 'http://jsonplaceholder.typicode.com/comments'
}]);

Then you'd use the service in your controller using e.g.

MyService.get($scope.accessLevel).then(function(data){
  $scope.response = data;
});

I hope you got the idea. Simple Plunker here http://plnkr.co/edit/GLmVmh

share|improve this answer
    
thank you! that's got me about halfway there, but now I can't figure out how to get it work with checkboxes instead of radio buttons. See plnkr.co/edit/C83MFP Not sure how to get to work when a user can select multiple widgets (each with their own endpoint). Is there a way to repeat the action w/out losing the other call results? Or is my understanding right I can't do this with a singleton? – kl02 Aug 11 '14 at 4:51
    
Put up something hacky based on you plunk plnkr.co/edit/mWWciY See also docs.angularjs.org/guide/providers – Mikko Viitala Aug 11 '14 at 7:29

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.