简体   繁体   中英

In an AngularJS app how can I use the results of one function for another?

I'm still fairly new to AngularJS and I'm stuck on something that I think I'm over complicating. In one of my controllers I have two functions that call my data factory but I need the second function to use the results from the first function.

When I use the snippet it below I keep getting order undefined. I don't want to put the second function in the success portion of the first. How can I pass the results to the second call?

app.controller('joDetailCtrl',
function ($modal, $scope, $http, modalService, dataFactory, $routeParams) {

    dataFactory.getJobOrder($routeParams.joNumber)
        .success(function (order) {
            $scope.status = 'Retrieved job order details';
            $scope.order = order;
        })
        .error(function (error) {
            $scope.status = 'Error retrieving job order details ' + error.message;
        });

    dataFactory.getJobOrderDetails(order[0].customerID, order[0].jobOrderID)
        .success(function (details) {
            $scope.status = 'Retrieved job order line items';
            $scope.details = details;
        })
        .error(function (error) {
            $scope.status = 'Error retrieving line items' + error.message;
        });
});

Watch the order on the scope:

$scope.$watch("order", function(newValueOfOrder){
  //call your other function here if newValueOfOrder is set

});

You get undefined because getJobOrder might not be fully executed and scope variables assigned before call to getJobOrderDetails , since functions are asynchronous. You can chain promises though.

You get the idea? Plunker here http://plnkr.co/edit/bzMhsW

angular.module('app', [])

  // Controller
  .controller('Ctrl', function($scope, $q, dataFactory) {
    // Get some order and it's details
    $scope.status = 'Please wait...';
    getOrder({ joNumber: 123 }).then(getDetails);

    // Wrapper for factory 
    function getOrder(job) {
      return dataFactory.getJobOrder(job.joNumber)
        .then(function(order) {
          $scope.status = 'Retrieved job order';
          $scope.order = order;
          return $q.when(order);
        });
    }

    // Other wrapper for factory    
    function getDetails(order) {
      return dataFactory.getJobOrderDetails(order[0].customerID, order[0].jobOrderID)
        .then(function(details) {
          $scope.status = 'Retrieved order line items';
          $scope.details = details;
        });
    }
  })

  // Mock data factory
  .factory('dataFactory', function($q, $timeout)  {
     return {
        getJobOrder: function(joNumber) {
          return $timeout(function() {
            return $q.when([{
              customerID: Math.floor((Math.random() * 10) + 1),
              jobOrderId: joNumber
            }]);          
          }, 1000);
        },  
        getJobOrderDetails: function(customerID, jobOrderID) {
          return $timeout(function() {
            return $q.when({
              details: 'details'
            });
          }, 1000);
        }
      };
  });

<body ng-controller="Ctrl">
  <div>status:{{ status }}</div>
  <div>order:{{ order | json }}</div>
  <div>details:{{ details | json }}</div>
</body>

I don't set up my controller in that fashion that you have with the appfactories. However, in my app, I have used the results from one function in my controller and have had it passed to another function in that same controller.

This example uses a bargraph from d3js so I cut out misc. material so it doesn't lengthen this answer. Just concentrate on the $scope.bardata in my example. This is what I'm using as a "result that is being passed to another function" as stated in your question.

I just set a global $scope.bardata variable that can be accessible via any function in my controller. In this case, I'm making an asynchronous call that grabs data, and then taking that data and passing it into my other function which controls the display of my bargraph.

So in the example below, I have my controller "ResultsCtrl" and my two functions "d3j" (bargraph displays) and "getResultsWaiting" (asynchronous call for the data to display to the bargraph). The results being passed between the two functions is called "bardata." I set this "bardata" as a global scope within the controller. You'll see it viewed as "$scope.bardata" NOT encased in any function. It is outside the functions.

Here is my code:

conferenceApp.controllers.controller('ResultsCtrl', function($scope, $log, $routeParams){

    $scope.bardata = $scope.bardata || {};

    $scope.d3j = function () {
        var bardata = $scope.bardata;
        var names = ['Hangout1', 'Hangout2', 'Hangout3'];
        ...etc etc.
        };

    $scope.getResultsWaiting = function () {

    gapi.client.conference.getResultsWaiting({
        webSafeKey: $routeParams.webSafeKey
    }).
        execute(function(resp){
            $scope.$apply(function() {
                if (resp.error){
                    $log.error('There was an Error');
                }
                else {
                    $log.info("Success");
                    $scope.webSafeKey = $routeParams.webSafeKey;

                    $scope.results = []
                    $scope.result=[]
                    angular.forEach(resp.items, function(result){
                        $scope.results.push(result);
                    });
                    $scope.bardata = JSON.parse(resp.items[0]['finalResults']);
                    $scope.d3j();
                    ...etc etc.
                    };

Because I'm using $scope.bardata as a global, I can pass it between functions in one controller.

Hope this can spring more ideas for you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM