Search code examples
javascriptjqueryajaxopenlayersarcgis-js-api

Accessing nested JSON data via jQuery ajax request


I have a problem with accessing json data via a jquery-ajax request in JavaScript. I keep hitting against a 'Cannot read property [0] of undefined' error that I get in G. Chrome's console. I have tried to refer to other features than feature '0', as well as not specifying any, but I still get not results when running my script on browser and searching for one of the json Sources (going from 0001 to 0012).

This is part of my education so I have to access the data in this specific way. I'll attach my code, which relies also on jquery-1.7.1.min.js and ol.js libraries. I'll be immensely grateful to whom will have a lead on what I'm doing wrong.

<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.5.0/build/ol.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.14/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>

<div class="pagewrapper">
  <div id="header"></div>
  <div id="controls">
    <h1>Controls</h1>
    <div ng-app="myApp" ng-controller="locationController">
      Enter SourceID(from 0001 to 0012):
      <input ng - model="location.Source">
      <button class="btn btn-default" ng - click="location.getElevation()">Search</button>
      <p>Elevation: {{location.ele}}</p>
    </div>
  </div>
var mainApp = angular.module("myApp", []);

mainApp.controller('locationController', function($scope) {
  $scope.location = {
    Source: ('0001'),
    getElevation: function() {
      $.ajax({
        url: 'https://services.arcgis.com/Sf0q24s0oDKgX14j/arcgis/rest/services/gpsData/FeatureServer/0/query?where=Source=' + $scope.location.Source + '&outFields=*&f=geojson',
        method: 'GET',
        success: function(response) {
          $scope.location.ele = response.features[0].properties.ele;
          $scope.$apply();
        },
        error: function() {}
      })
    }
  }
})

Solution

  • Just ran your code. As other pointed, is important to run console.log on the results to debug. On your case, added a console.log at success's function

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml: lang="en-gb" lang="en-gb">
    <head>
        <meta http - equiv="content-type" content="text/html; charset=utf-8" />
        <script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.5.0/build/ol.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.14/angular.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
        <title> Trial
        </title>
        </script>
        </script>
        <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js">
        </script>
    </head>
    <body>
        <div class="pagewrapper">
            <div id="header">
            </div>
    
            <div id="controls">
                <h1> Controls
                </h1>
    
                <div ng-app="myApp" ng-controller="locationController">
                    Enter SourceID(from 0001 to 0012):
                    <input ng-model="location.Source">
                    <button class="btn btn-default" ng-click="location.getElevation()"> Search</button>
                    <p>Elevation: {{location.ele}}</p>
                </div>
            </div>
    
            <script>
                var mainApp = angular.module("myApp", []);
                mainApp.controller('locationController', function($scope) {
                    $scope.location = {
                        Source: ('0001'),
                        getElevation: function() {
                            $.ajax({
                                url: 'https://services.arcgis.com/Sf0q24s0oDKgX14j/arcgis/rest/services/gpsData/FeatureServer/0/query?where=Source=' +
                                    $scope.location.Source + '&outFields=*&f=geojson',
                                method: 'GET',
                                success: function(response) {
                                    console.log(response)
                                    $scope.location.ele = response.features[0].properties.ele;
                                    $scope.$apply();
                                },
                                error: function() {}
                            })
                        }
                    }
                })
            </script>
    </body>
    </html>
    

    It got a response like this: Response ajax

    But that is a string, not an object. Look a this log:

    console.log(typeof response) // result is string
    

    So you are trying to access a key on a string instead of a object, so you need to parse the string to an object, for example like this:

    JSON.parse(response)
    

    So it is really:

    JSON.parse(response).features[0].properties.ele
    

    That will make your code work: Working code

    EDIT: To access other data, you need to define the variable of the object you need at the function, and the render on the DOM. For example, latitude:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml: lang="en-gb" lang="en-gb">
    
    <head>
        <meta http - equiv="content-type" content="text/html; charset=utf-8" />
        <script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.5.0/build/ol.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.14/angular.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
        <title> Trial
        </title>
        </script>
        </script>
        <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js">
        </script>
    </head>
    
    <body>
        <div class="pagewrapper">
            <div id="header">
            </div>
    
            <div id="controls">
                <h1> Controls
                </h1>
    
                <div ng-app="myApp" ng-controller="locationController">
                    Enter SourceID(from 0001 to 0012):
                    <input ng-model="location.Source">
                    <button class="btn btn-default" ng-click="location.getElevation()"> Search</button>
                    <p>Elevation: {{location.ele}}</p>
                    <p>Latitude: {{location.lat}}</p>
                </div>
            </div>
    
            <script>
                var mainApp = angular.module("myApp", []);
                mainApp.controller('locationController', function($scope) {
                    $scope.location = {
                        Source: ('0001'),
                        getElevation: function() {
                            $.ajax({
                                url: 'https://services.arcgis.com/Sf0q24s0oDKgX14j/arcgis/rest/services/gpsData/FeatureServer/0/query?where=Source=' +
                                    $scope.location.Source + '&outFields=*&f=geojson',
                                method: 'GET',
                                success: function(response) {
                                    $scope.location.ele = JSON.parse(response).features[0].properties.ele;
                                    $scope.location.lat = JSON.parse(response).features[0].geometry.coordinates[1];
                                    $scope.$apply();
                                },
                                error: function() {}
                            })
                        }
                    }
                })
            </script>
    </body>
    </html>
    

    Will give you: With latitude