0

I'm making an Angularjs/nvd3 dashboard with a number of widgets using json input. I've got a widget to work, but what I'm trying is to reuse an Angular service to return data based on a different url provided per widget.

My code in Javascript:

var fixedUrl = "http://static_url/data.json";

var myApp = angular.module("nvd3myApp", ['nvd3ChartDirectives']);

myApp.service('dataService', function($http) {
    this.getData = function(callbackFunc) {
        return $http.get(fixedUrl);
    }
});

myApp.controller('Widget3Controller', function($scope, dataService){
    //Get the data
    dataService.getData().then(function(dataResponse) {
        data = dataResponse.somelogictotransformit();

        eval 
        $scope.exampleData = [
            {
                "key"   : "Widget title",
                "color" : "#1f77b4",
                "values": data
            },
        ];

        $scope.xAxisTickFormatFunction = function(){
            return function(d){
                return d3.time.format('%H:%M')(new Date(d));
            }
        }
        $scope.yAxisTickFormatFunction = function(){
            return function(d){
                return d3.format(',d')(d);
            }
        }
    });
});

And the code in the html:

<div id="container" ng-controller="Widget3Controller" ng-app='nvd3myApp'>
    <nvd3-multi-bar-chart [.......]></nvd3-multi-bar-chart>
</div>

So what I'd like to do is to have a different url (instead of using fixedUrl) per widget, but I'm unable to have myApp's dataService to take an extra variable.

I'd like to do something like dataService.getData(someUrl), and preferably even use the same controller for multiple widgets based on some html tag.

Thanks for any help.

Base_v
  • 308
  • 5
  • 13

2 Answers2

0

you can use .value simply as you using .service or .controller :

myApp.value('url', 'http://static_url/data.json');

and then inject it in your controller/service

myApp.service('dataService', ['url', function($http) {
    this.getData = function(callbackFunc) {
        return $http.get(url);
    }
}]);

this value can be overrided - just redifine it.

another way - to write .factory with some parameters (for url creating) and then return url string, and also inject it in your .service or simply throw params in your .service like that :

myApp.service('dataService', function($http){
    return ({
        getData/*public*/:getData /*private*/
    })
    function getData(urlPath1, urlPath2){
        var url = "http://" + urlPath1 + urlPath2 + "/data.json";
        return $http.get(url);
    }
}
//inside controller : 
dataService.getData(static_url, static_urlPart2).then(...)
un.spike
  • 4,857
  • 2
  • 18
  • 38
0

Why don't you use a directive? Define the URL on the directive level...

myApp.directive('widget3', function() {
    return {
        scope : {
            url : '@'
        },
        controler: 'Widget3Controller',
        replace: true,
        template :'<div><nvd3-multi-bar-chart [.......]></nvd3-multi-bar-chart></div>'
    }
});

..and then get the URL form the scope.

myApp.controller('Widget3Controller', function($scope, dataService){
    //Get the data
    dataService.getData($scope.url).then(function(dataResponse) {
        data = dataResponse.somelogictotransformit();
Michael
  • 3,085
  • 1
  • 17
  • 15