0

I'm having trouble accessing keys and values in my json file. I've tried a bunch of things but my focus is shot this week and I'm stuck.

Here's my transport.json file..

{"transportation":[
    {"Springfield":[{
        "bus":[{
            "start": 6,
            "end": 24,
            "stops":["oak street", "main street"]
        }],
        "taxi":[{
            "start": 25,
            "end": 25,
            "stops":["all"]
        }]
    }]},
    {"Pleasantville":[{
        "bus":[{
            "start": 6,
            "end": 22,
            "stops":["centre street", "river street"]
        }],
        "taxi":[{
            "start": 25,
            "end": 25,
            "stops":["all"]
        }],
        "train":[{
            "start": 6,
            "end": 23,
            "stops":["uptown", "downtown"]
        }]
    }]}
]}

The two things I'm trying to do are..

  1. I want to be able to alert the bus start value in users current area.

  2. I want to loop through the bus stops to compare to users current stop.

Here's my js code..

var currentArea = 'Pleasantville'; // this variable changes
var currentStop = 'uptown'; // this variable changes
$.getJSON("transport.json", function(jsontransportation) {
    $(jsontransportation.transportation).each(function(dataaaa) {
        var areaName = Object.keys(this);
        if (areaName == currentArea) { // this works to find correct area in json
            $(this.bus).each(function(key, value) { // i can't get this loop to work
                alert(this.start); // alerts nothing, no errors
                $(this.stops).each(function(key) { // now im trying to loop through keys in 'stops'
                    if (this.key === currentStop) { // to compare stop to current area
                        alert('the bus stops here at ' + currentStop); // and alert if there is a stop here
                    } else {
                        alert('the bus does not stop here at ' + currentStop); // else alert no stop here
                    }
                })
            });
        }
    });
});
Hastig Zusammenstellen
  • 4,286
  • 3
  • 32
  • 45
  • Can you post what output you are trying to achieve? – Ali Rasheed Jul 01 '17 at 07:34
  • @AliRasheed For 1. I just want to alert the value for now. I'll be saving it as a variable for some calculations in the final script. For 2. I need to check if the stop exists for the users current location (bus/train/transit stop). And a bunch of other things, this is just a stripped down version of the json and js files. – Hastig Zusammenstellen Jul 01 '17 at 07:38
  • @HastigZusammenstellen have a look at my answer. I guess you intend to alert the message only once rather that alert on each element on the stops array. – Ankit Agarwal Jul 01 '17 at 08:03
  • @AKA Thanks man, I'm just working through your answer now. I appreciate your fix, I realized I made that error after trying out the earlier answers. I'll try and decide what's best before I crash tonight, or tomorrow evening. – Hastig Zusammenstellen Jul 01 '17 at 08:19
  • Sure @HastigZusammenstellen . hope to get positive feedback from you and at least a up vote for the work. – Ankit Agarwal Jul 01 '17 at 08:20
  • @AKA Ohh for sure and I appreciate the time you've taken to answer but I take it very serious. As soon as I get through each answer and am certain they work I do the upvoting. :) – Hastig Zusammenstellen Jul 01 '17 at 08:24
  • @HastigZusammenstellen yes that is really a positive thinking. – Ankit Agarwal Jul 01 '17 at 08:25

4 Answers4

1

you are using wrong keys at various places, actually to check if bus stops at user's current stop, you don't need to loop through all stops and compare instead you can use indexOf(), following code should work:

var currentArea = 'Pleasantville'; // this variable changes
var currentStop = 'uptown'; // this variable changes
$.getJSON("transport.json", function(jsontransportation) {
    $(jsontransportation.transportation).each(function(dataaaa) {
        var areaName = Object.keys(this)[0];
        if (areaName == currentArea) { // this works to find correct area in json
        var selectedCityObject = this[areaName][0]
            $(selectedCityObject.bus).each(function(key, value) { // i can't get this loop to work
                alert(value.start); // alerts nothing, no errors
                if (value.stops.indexOf(currentStop) >= 0) { // to compare stop to current area
                        alert('the bus stops here at ' + currentStop); // and alert if there is a stop here
                    } else {
                        alert('the bus does not stop here at ' + currentStop); // else alert no stop here
                    }
            });
        }
    });
});
Dij
  • 9,761
  • 4
  • 18
  • 35
1

try this:

var currentArea = 'Pleasantville'; // this variable changes
var currentStop = 'uptown'; // this variable changes
$.getJSON("transport.json", function(jsontransportation) {
    $(jsontransportation.transportation).each(function(index, area) {
        var areaName = Object.keys(this)[0];
        if (areaName == currentArea) { 
        vehicles = this[areaName][0];
            $(vehicles.bus).each(function(key, value) { 
                alert(value.start);
                $(value.stops).each(function(index, stopName) {
                    if (stopName === currentStop) { 
                        alert('the bus stops here at ' + currentStop); 
                    } else {
                        alert('the bus does not stop here at ' + currentStop);
                    }
                })
            });
        }
    });
});
Victor Radu
  • 2,262
  • 1
  • 12
  • 18
1

Here is exactly what you need. I have also changed the code so that the alert is displayed only once.

$(document).ready(function(){
   var currentArea = 'Pleasantville'; // this variable changes
   var currentStop = 'uptown'; // this variable changes
  $.getJSON("transport.json", function(jsontransportation) {
      $(jsontransportation.transportation).each(function(dataaaa) {
          var areaName = Object.keys(this);
          if (areaName == currentArea) { 
             var selectedArea = this[currentArea];
             var bus = selectedArea[0].bus;
             var stops;
             $(bus).each(function(keyBus, valueBus) { 
               alert(this.start); 
               stops = false;
               $(this.stops).each(function(key, valueStops) { 
                      if (valueStops === currentStop) { 
                          stops = true;
                      } 
                  })
             });
             if(stops){
                alert('the bus stops here at ' + currentStop); 
             }else{
                alert('the bus does not stop here at ' + currentStop); // else alert no stop here
             }


          }
      });
  });
});

For work around here is the link to PLUNKR

Ankit Agarwal
  • 30,378
  • 5
  • 37
  • 62
  • Thanks again AKA. Your answer addressed what I asked for and also saw through the question to answer what I would have needed next. (the unnecessary alerts at each iteration) – Hastig Zusammenstellen Jul 01 '17 at 08:57
0

Try changing serviceType to get your data chunk. (Sorry, No jquery)

var $data = {
  "transportation": [{
      "Springfield": [{
        "bus": [{
          "start": 6,
          "end": 24,
          "stops": ["oak street", "main street"]
        }],
        "taxi": [{
          "start": 25,
          "end": 25,
          "stops": ["all"]
        }]
      }]
    },
    {
      "Pleasantville": [{
        "bus": [{
          "start": 6,
          "end": 22,
          "stops": ["centre street", "river street"]
        }],
        "taxi": [{
          "start": 25,
          "end": 25,
          "stops": ["all"]
        }],
        "train": [{
          "start": 6,
          "end": 23,
          "stops": ["uptown", "downtown"]
        }]
      }]
    }
  ]
};

var search = function(currentArea, currentStop, serviceType, callback) {
  var found = false;
  $data.transportation.forEach(function(area) {
    var $transport = area[currentArea];
    if ($transport) {
      $transport.forEach(function($types) {
        $service = $types[serviceType];
        if ($service) {
          $service.forEach(function($details) {
            if ($details.stops.indexOf(currentStop) > -1) {
              found = $details;
            }
          });
        }
      });
    }
  });

  setTimeout(function() {
    callback(found, currentArea, currentStop, serviceType);
  }, 0);
};

function response(data, currentArea, currentStop, serviceType) {
  if (data === false) {
    alert("The " + serviceType + " doesn't stop at " + currentStop + " for " + currentArea);
  } else {
    alert(serviceType + " starts at " + data.start + " at " + currentStop + ", " + currentArea);
  }
}

var currentArea = 'Pleasantville';
var currentStop = 'uptown';

search(currentArea, currentStop, 'bus', response);
search(currentArea, currentStop, 'train', response);
search(currentArea, 'river street', 'bus', response);
search('Springfield', 'oak street', 'bus', response);
Priya
  • 1,522
  • 1
  • 14
  • 31
  • Why are you using setTimeout? – Ankit Agarwal Jul 01 '17 at 08:14
  • The solution is to "pause" the JavaScript execution to let the rendering threads catch up. And this is the effect that setTimeout() with a timeout of 0 does. ref: https://stackoverflow.com/questions/779379/why-is-settimeoutfn-0-sometimes-useful – Priya Jul 01 '17 at 08:15
  • Hi Priya, thanks for taking your time to help me but I couldn't see in your code where it alerted the 'start' value. – Hastig Zusammenstellen Jul 01 '17 at 08:55
  • `console.log(found)` is nothing but a js printing statement like `alert`. You can do an alert too for the found variable. if your service type is train `alert(JSON.stringify(found))` will give you `{"start": 6, "end": 23, "stops": ["uptown", "downtown"]}` else `false`. Console shows data in developer toolbar – Priya Jul 01 '17 at 08:58
  • @HastigZusammenstellen now you can check alerting the data. – Priya Jul 01 '17 at 09:06
  • @Priya What I meant was it's getting/alerting/logging the entire bus object, not alerting the single 'start' value which was all I needed for the first part of my problem. – Hastig Zusammenstellen Jul 01 '17 at 09:22
  • @Priya Actually, it's currently alerting the 'train' object, not 'bus'. – Hastig Zusammenstellen Jul 01 '17 at 09:23
  • Give any search you want. it will show you what you want and where. – Priya Jul 01 '17 at 09:43
  • @Priya read the question properly before you come up with anything, The OP seeks to have a easy answer that is straight forward for them to understand. – Ankit Agarwal Jul 01 '17 at 09:56