How to pass JSON response to model for use in GET request

时间:2015-11-01 01:41:49

标签: angularjs

I'm accessing an API which returns some JSON about nutritional information. I'm able to store the response in the model, display it, all that good stuff. I just chuck it into $scope.response = data.item.name but there is another property which I would like to use to form a new request to the server.

I want to take data.item.ndbno, store it in $scope.querySelection = data.item.ndbno and use it as a parameter in the new request. I have tried using ng-value={{item.ndbno}}, and accessing it directly via index in the model alone. Basically for the end resoult, I would like to be able to click on any result in the list, and send a get request with that ndbno to the server. Currently the code sends an undefined ndbno like so

POST http://api.nal.usda.gov/ndb/reports/?ndbno=undefined&type=b&api_key=DEMO_KEY&format=json&callback=JSON_CALLBACK 400 (Bad Request).

I don't know what I'm doing wrong. I'm sorry if this has an obvious solution to someone who's seasoned, but I'm a newbie, and I never used jQuery.

Here's my complete code. And just as a show of gratitude, whomever can help me, I will credit in the credits of the finished app.

<!DOCTYPE html>
<html lang="en" ng-app="sugarApp">
  <head>
    <meta charset="UTF-8"/>
    <title>Sugar App</title>
    <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/angular_material/0.9.4/angular-material.min.css">
    <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap.css"/>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.7/angular.min.js"></script> 
  </head>
  <body ng-controller="loadingController">
    <div class="alert alert-info" ng-show="loading">Loading</div> <!-- show/hide based on the truthy or falsey value of $scope.loading-->
    <div ng-controller="sugarController">
        <form name="searchForm"  ng-submit="doSearch()">
            <input type="text" ng-model="queryInput" placeholder="Search a food or food product">
            <input type="submit" value="Search">
        </form>
        <ul>
            <div ng-show="query">
            Results for '{{baseList.q}}'
                 <li ng-repeat="item in queryResult">

                <!-- the problem : ndbno parameter is not being passed, and as a result the request has an undefined value
                tried: baseList.ndbno, item.ndbno, $scope.baseList.ndbno, ng-value, bracket syntax [], other things i'm forgetting-->
                    <a href ng-click="showResults()">{{item.name}}, {{item.ndbno}}</a>
                     <span ng-model="ndbnum" ng-bind="item.ndbno"></span>>

                 </div>
            </li>
            <md-card> 
            <md-card-content>
                The amount of sugar in <strong>{{prodDetail.nutrients[8].measures[3].eqv * .0353}}</strong>oz of <strong>{{prodDetail.name}}</strong> is <strong>{{prodDetail.nutrients[8].measures[3].value}}g</strong>, or <strong>{{prodDetail.nutrients[8].measures[3].value / 7}} circus peanuts</strong>, or <strong>{{prodDetail.nutrients[8].measures[3].value / 4}} teaspoons</strong> of granulated sugar.
                    <footer>
                    <small>Source: National Nutrient Database for Standard Reference - Release {{baseReport.sr}}</small>
                </footer>
            </md-card-content>
            </md-card>
        </div>
      </ul>


      <div ng-show="result"> <!-- show/hide based on the truthy or falsey value of $scope.result-->
        The amount of sugar in {{baseList.sr}} of {{prodDetail.name}} is {{prodDetail.amount}} or circus peanuts or teaspoons of granulated sugar.
      </div>


    </div>

    <script>
/* TODO
    high
    clean up code: remove redundancies
    figure out how to pass the ndbno result to $scope.querySelection 

    low
    replace deprecated .success with .then
    reformat get requests into factory
    */
    angular.module('sugarApp',[]).controller('sugarController',['$scope','$http',function($scope,$http){
        $scope.doSearch = function(){ 
        $scope.$emit('LOAD'); //using $emit to signal when/vhen not to show the loading indicator 
        $scope.$emit('UNQUERY'); //using $emit to signal when/when not to show the search results view
        $scope.searchUrl = 'http://api.nal.usda.gov/ndb/search/';
        $scope.testUrl = 'http://api.nal.usda.gov/ndb/reports/?ndbno=14400&type=f&format=json&api_key=DEMO_KEY';
        $scope.api_key = '&api_key=DEMO_KEY';
        $scope.fmtJson = '?format=json';
        $scope.q = '&q=';
        $scope.callback = '&callback=JSON_CALLBACK';

            $scope.query = $scope.queryInput;

        $scope.fullUrl= $scope.searchUrl + $scope.fmtJson + $scope.q + $scope.query + $scope.api_key + $scope.callback;
        $scope.placeholder = "Search for a food or food product";
        //temporary comment out $scope.baseReport = {}; //initialize a blank baseReport array
        $http.get($scope.fullUrl)
        .success(function(data){
            //$scope.baseReport=data.report;
            $scope.baseList=data.list;
            $scope.queryResult=data.list.item;
            $scope.ndbnum = data.list.item.ndbno;
            $scope.$emit('UNLOAD');
            $scope.$emit('QUERY');
            $scope.$emit('NORESULT');
        })}

            $scope.showResults = function(){
            $scope.$emit('UNQUERY');
            $scope.$emit('LOAD');
            $scope.$emit('RESULT');
            $scope.resultBaseUrl = 'http://api.nal.usda.gov/ndb/reports/';
            $scope.ndb = '?ndbno=';

$scope.querySelection = $scope.ndbnum;

            $scope.rtype = '&type=b'
            $scope.fmtJson = '&format=json';
            $scope.api_key = '&api_key=DEMO_KEY';
            $scope.callback = '&callback=JSON_CALLBACK';
            //temporary comment out $scope.baseReport = {};
            $scope.resultUrl= $scope.resultBaseUrl + $scope.ndb + $scope.querySelection + $scope.rtype
            + $scope.api_key + $scope.fmtJson + $scope.callback;

            $http.post($scope.resultUrl)
            .success(function(data){
                $scope.baseReport=data.report;
                $scope.prodDetail=data.report.food;
                $scope.$emit('UNLOAD');
            })
        }

    }])
    //setting up scope emit flags for use in showing/hiding view elements
        //used for showing or hiding results div
    .controller('resultController', ['$scope', function($scope){
        $scope.$on('RESULT',function(){$scope.result=true});
        $scope.$on('NORESULT',function(){$scope.result=false});
    }]) //used for showing or hiding query list view div
    .controller('queryController', ['$scope', function($scope){
        $scope.$on('QUERY',function(){$scope.query=true});
        $scope.$on('NOQUERY',function(){$scope.query=false});
    }]) // used for showing or hiding the loading indicator div
    .controller('loadingController',['$scope',function($scope){
        $scope.$on('LOAD',function(){$scope.loading=true});
        $scope.$on('UNLOAD',function(){$scope.loading=false});
    }])
    </script>
  </body>
</html>

2 个答案:

答案 0 :(得分:2)

在您的代码中,您使用ndbno作为item

的属性
$scope.ndbnum = data.list.item.ndbno;

但是ndbno不是data.list.item的直接属性,而是它是数组中对象的属性

enter image description here

如果想访问ndbno,您必须通过索引访问

喜欢

console.log(data.list.item[0].ndbno);

答案 1 :(得分:1)

或者没有索引你可以试试这样的东西。

html:

    <li ng-repeat="item in queryResult track by $index">
        <a href ng-click="showResults(item.ndbno, $index)">{{item.name}}, {{item.ndbno}}</a>
    </li>

角度:

$scope.showResults = function(ndbno, id){
    .
    .
    .
    // with an index
    $scope.ndbnum = queryResult[id].ndbno
    // OR a bit easier without an index
    $scope.ndbnum = ndbno
    .
    .
    .
}

$index跟踪可能会过于复杂,因为每个ng-repeat都有自己的$index,而且这些可以嵌套,因此很难判断哪个$index正在大型模板中使用。

我建议只将值直接传递给控制器​​。但是,如果您需要知道它确实来自哪个对象,那么使用$index是您的下一个目标。

Angular会自动将$index附加到ng-repeat范围,而没有必要track by你只能使用$index,但这会让人感到困惑正在使用$index,除非您明确将$index设置为track by以外的其他变量名称,否则父母$index可能会变得棘手