passing angular service data to gaugechart control

2019-07-22 04:30发布

问题:

I have a gauge-chart controller in my project which has to show data from an angular service. But it won't accept the data from service when I call the service function . Here is what I am trying :

 Controller.js

 angular.module("app.controllers", [])
 .controller("gaugeCtrl", ["$scope","config","myService",
  function ($scope,config,myService) {
    $scope.gaugeHome = {

      gaugeData: myService.getdata(),
      gaugeOptions: {
        lines: 12,
        angle: 0,
        lineWidth: 0.47,
        pointer: {
          length: 0.6,
          strokeWidth: 0.03,
          color: "#555555"
        },
        limitMax: "false",
        colorStart: config.secondary_color,
        colorStop: config.secondary_color,
        strokeColor: "#F5F5F5",
        generateGradient: !0,
        percentColors: [
          [0, config.secondary_color],
          [1, config.secondary_color]
        ]
      }
    }
  ])

This is my Service Data .It does fetch the data but unable to pass to the controller val field in controller code

  var demoService= angular.module('demoService',[])
  .service('myService',function($http,$q){
   var deferred = $q.defer();
  $http.get('http://enlytica.com/RSLivee/rest/census').then(function(data)
   {
     deferred.resolve(data);
 /*var v=0;
 $players=data.data;
    console.log($players.Tweets);
     ($players.Tweets).forEach(function(index, element) {
         v=v+ (index.FAVOURITE_COUNT);
         console.log(index.FAVOURITE_COUNT); 
     });
     console.log(v);
     deferred.resolve(v);*/
   });


this.getdata=function()
{  

var dataarr = [];
var v=0;
deferred.promise.then(function(data)
        {

    $players=data.data;
    console.log($players.Tweets);
     ($players.Tweets).forEach(function(index, element) {
         v=v+ (index.FAVOURITE_COUNT);
         console.log(index.FAVOURITE_COUNT); 
     });
     console.log(v); 
     dataarr.push({ maxValue: 3e3,animationSpeed: 100,val: v})
     console.log(dataarr);
    });

 return (dataarr);

 }
})

I also tried to get the data in controller.js like following , but it didnt work either :

angular.module("app.controllers", []).controller("gaugeCtrl",["$scope","config","myService",
function ($scope,config,myService) {
var v=0;
var dataarr=[];
 var promise=myService.getdata();
console.log(promise);
var tp=promise.then(function(data)
        {
    $players=data.data;
    console.log($players.Tweets);
     ($players.Tweets).forEach(function(index, element) {
         v=v+ (index.FAVOURITE_COUNT);
        // console.log(index.FAVOURITE_COUNT); 
     });
     console.log(v);
     dataarr.push({ maxValue:800,animationSpeed: 100,val: v});
     console.log(dataarr);
     return dataarr;
    });
   ]}

but dataarr or v values cant be accessed . IS there a way using which i could pass value to my gauge.

Thanks in advance

@OrenD I changed the Service.js code :[i removed the DI as it threw an error -->

  Error: [ng:areq] http://errors.angularjs.org/1.3.14/ng/areq?      
 p0=fn&p1=not%20aNaNunction%2C%20got%string
 at Error (native)
at http://localhost:8080/Enlytica18thOnwards/dist/js/app.js:14:4847
at Sb (http://localhost:8080/Enlytica18thOnwards/dist/js/app.js:14:11576)
at tb (http://localhost:8080/Enlytica18thOnwards/dist/js/app.js:14:11670)
at Function.ab.$$annotate (http://localhost:8080/Enlytica18thOnwards/dist/js/app.js:16:25928)
at e (http://localhost:8080/Enlytica18thOnwards/dist/js/app.js:14:19914)
at Object.instantiate (http://localhost:8080/Enlytica18thOnwards/dist/js/app.js:14:20199)
at Object.<anonymous> (http://localhost:8080/Enlytica18thOnwards/dist/js/app.js:14:20480)
at Object.e [as invoke] (http://localhost:8080/Enlytica18thOnwards/dist/js/app.js:14:20075)
at Object.$get (http://localhost:8080/Enlytica18thOnwards/dist/js/app.js:14:19010) ]


 Service .js


 var demoService= angular.module('demoService',[])
 .service('myService', function($http, $q) {
  this.getData = function() {
   return $http.get('http://enlytica.com/RSLivee/rest/census')
    .then(function(data) {
      var v = 0;
      for (var i = 0; i < data.data.Tweets.length; ++i) {
        v += data.data.Tweets[i]['FAVOURITE_COUNT'];
      }
      console.log(v);//doesnt show anything on console
      return $q.when([{
        maxValue: 3e3,
        animationSpeed: 100,
        val: v
      }]);
    });
   };
  }
);

But now this doesn't read data from the url.Anything that i am doing wrong ?

回答1:

Try this:-

    app.factory("companyData", function ($http) {
return {
        getAll: function (items) {
            var path = "https://dl.dropboxusercontent.com/u/28961916/companies.json"
            $http.get(path).success(items);
        }
    }
});
letus consider this is a service
here this returns items object
if I want to use that items object in controller app.controller("mainController", function ($scope, companyData) {
    //console.log(companyData.getAll());
    companyData.getAll(function (companyDetails) {
        console.log(companyDetails)
    }
    }


回答2:

It is recommended for services to return promises since in a lot of cases the requested data is asynchronously fetched from the back-end.

Following is a rough implementation of the service to provide a promise you can use in the controller:

app.service('myService', ['$http', '$q', function($http, $q) {
    this.getData = function() {
      return $http.get('http://enlytica.com/RSLivee/rest/census')
        .then(function(data) {
          var v = 0;
          for (var i = 0; i < data.data.Tweets.length; ++i) {
            v += data.data.Tweets[i]['FAVOURITE_COUNT'];
          }
          return $q.when([{
            maxValue: 3e3,
            animationSpeed: 100,
            val: v
          }]);
        });
    };
  }
]);

Now, in the controller, you would have to act upon the resolution of the provided promise. You have several alternatives:

  • You could initialize $scope.gaugeHome with data that would be sufficient for your view until the actual data is received from the service and then set the gaugeData property when the promise is resolved.
  • You could add a call to the myService.getData() function in the resolve section of your router configuration for that controller. This way you can inject the resolved promise to the controller and have the data ready without calling the getData() function from within the controller. Note that in this alternative the view will not be prepared/displayed until the data is fetched from the backend.

Here is a code snippet showing the way you can update gaugeData with the resolved promise's data:

app.controller('gaugeCtrl', ['$scope', 'config', 'myService',
  function($scope, config, myService) {
    $scope.gaugeHome = {
      gaugeData: [],
      gaugeOptions: {
        lines: 12,
        angle: 0,
        lineWidth: 0.47,
        pointer: {
          length: 0.6,
          strokeWidth: 0.03,
          color: "#555555"
        },
        limitMax: "false",
        colorStart: config.secondary_color,
        colorStop: config.secondary_color,
        strokeColor: "#F5F5F5",
        generateGradient: !0,
        percentColors: [
          [0, config.secondary_color],
          [1, config.secondary_color]
        ]
      }
    }

    myService.getData().then(function(dataArr) {
      $scope.gaugeHome.gaugeData = dataArr;
    });
  }
]);