0

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.

kl02
  • 580
  • 6
  • 24

2 Answers2

0

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

Mikko Viitala
  • 8,344
  • 4
  • 37
  • 62
  • 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 http://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 04:51
  • Put up something hacky based on you plunk http://plnkr.co/edit/mWWciY See also https://docs.angularjs.org/guide/providers – Mikko Viitala Aug 11 '14 at 07:29
0

ApiMock is a minimal (1.68kb gzipped) library for AngularJS that allows you to mock your RESTful API by routing your API calls to static JSON files.

https://github.com/seriema/angular-apimock

Juri
  • 1,531
  • 2
  • 20
  • 43