SitePoint Sponsor

User Tag List

Results 1 to 10 of 10

Hybrid View

  1. #1
    SitePoint Addict jamus's Avatar
    Join Date
    Jul 2004
    Location
    Devon, UK
    Posts
    301
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Targeting an item of an object when the number of items changes?

    Hi,

    I have a json feed that I would like to extract information out from but for the last few days I've been struggling. I can target the item using the key but because the number of items in the object can vary which obviously then breaks my method.

    E.g

    Code:
    var dayone1260 = data.SiteRep.DV.Location.Period[0].Rep[0];
          console.log(dayone1260.Pp);
    My Json feed looks like this:
    Code:
    <DV dataDate="2012-11-01T18:00:00Z" type="Forecast">
    <Location i="310069" lat="50.7179" lon="-3.5327" name="EXETER" country="ENGLAND" continent="EUROPE">
    <Period type="Day" value="2012-11-01Z">
    <Rep D="W" F="5" G="25" H="71" Pp="48" S="9" T="8" V="EX" W="10" U="1">900</Rep>
    <Rep D="W" F="5" G="47" H="78" Pp="59" S="4" T="7" V="EX" W="13" U="0">1080</Rep>
    <Rep D="SW" F="3" G="25" H="82" Pp="58" S="9" T="6" V="EX" W="13" U="0">1260</Rep>
    </Period>
    <Period type="Day" value="2012-11-02Z">
    <Rep D="WSW" F="3" G="34" H="85" Pp="38" S="11" T="6" V="GO" W="19" U="0">0</Rep>
    <Rep D="WSW" F="3" G="20" H="80" Pp="1" S="9" T="6" V="EX" W="2" U="0">180</Rep>
    <Rep D="SW" F="3" G="18" H="86" Pp="9" S="7" T="5" V="VG" W="2" U="0">360</Rep>
    <Rep D="SSW" F="5" G="13" H="82" Pp="4" S="4" T="6" V="VG" W="3" U="1">540</Rep>
    <Rep D="WNW" F="6" G="22" H="77" Pp="28" S="7" T="8" V="VG" W="3" U="1">720</Rep>
    <Rep D="WSW" F="8" G="22" H="68" Pp="8" S="9" T="10" V="EX" W="3" U="1">900</Rep>
    <Rep D="WSW" F="5" G="18" H="78" Pp="1" S="7" T="7" V="EX" W="2" U="0">1080</Rep>
    <Rep D="SW" F="5" G="13" H="81" Pp="7" S="7" T="6" V="VG" W="2" U="0">1260</Rep>
    </Period>
    <Period type="Day" value="2012-11-03Z">
    <Rep D="WSW" F="4" G="13" H="82" Pp="2" S="7" T="6" V="EX" W="2" U="0">0</Rep>
    <Rep D="SW" F="3" G="16" H="83" Pp="7" S="7" T="6" V="EX" W="2" U="0">180</Rep>
    <Rep D="W" F="3" G="11" H="84" Pp="2" S="7" T="5" V="VG" W="2" U="0">360</Rep>
    <Rep D="W" F="2" G="18" H="85" Pp="38" S="9" T="5" V="GO" W="10" U="1">540</Rep>
    <Rep D="W" F="4" G="20" H="76" Pp="43" S="9" T="7" V="EX" W="10" U="1">720</Rep>
    <Rep D="WSW" F="2" G="18" H="82" Pp="44" S="9" T="5" V="VG" W="10" U="1">900</Rep>
    <Rep D="N" F="2" G="11" H="86" Pp="15" S="4" T="4" V="VG" W="7" U="0">1080</Rep>
    <Rep D="SSW" F="1" G="11" H="86" Pp="6" S="7" T="4" V="EX" W="0" U="0">1260</Rep>
    </Period>
    ....More reports
    </Location>
    </DV>
    </SiteRep>
    Is there a better way to obtain the .Pp value in a variable so I can then use / display it on the page. Using the 'value' of <Rep>?

    My javascript knowledge is limited to jquery front end stuff to date so sorry if I've not explained this very well.

  2. #2
    Under Construction silver trophybronze trophy AussieJohn's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, Australia
    Posts
    776
    Mentioned
    11 Post(s)
    Tagged
    0 Thread(s)
    Well, firstly, that definitely does not look like a JSON feed at all, that looks more like XML.

    If it *were* JSON, you would expect your data object to look like a JavaScript Object (http://www.json.org/js.html)
    e.g.
    Code javascript:
    data = {
        "DV": {
            "dataDate":"2012-11-01T18:00:00Z",
            "type": "Forecast",
            "Location": {
                "i": "310069",
                "lat": "50.7179",
                ...
                ...
                "Period": {
                    "type": "Day",
                    ...
                    "Rep":[
                        {
                            "TextValue": 900,
                            "D": "W",
                            "F": "5",
                            ...
                            ...
                        },
                        ...
                        ...
                    ]
                }
     
            }
        }
     
    }

    In any case, the way that you are currently retrieving the data is about as good as it gets, you can of course shorten the path a little if you only need to get access to the reps in a particular section of the code.

    Code javascript:
    // currently you have a rather long path to get to a rep
    var rep = data.SiteRep.DV.Location.Period[0].Rep[0];
     
    // you could shorten it like this
    var periods = data.SiteRep.DV.Location.Period;
     
    //you can now access the periods/reps like so:
    rep = periods[0].Rep[0];
    var details = {
    . . web: "afterlight.com.au",
    . . photos: "jvdl.id.au",
    . . psa: "usethelatestversion.com"
    }

  3. #3
    SitePoint Addict jamus's Avatar
    Join Date
    Jul 2004
    Location
    Devon, UK
    Posts
    301
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hi John,

    Thanks for your reply.

    Sorry. It is definately json. However, I have an extension for Chrome that displays the feed like that and I had just cut and paste it without thinking.

    The json looks like this:

    Code:
    "units":"C","$":"Feels Like Temperature"},{"name":"G","units":"mph","$":"Wind Gust"},{"name":"H","units":"%","$":"Screen Relative Humidity"},{"name":"T","units":"C","$":"Temperature"},{"name":"V","units":"","$":"Visibility"},{"name":"D","units":"compass","$":"Wind Direction"},{"name":"S","units":"mph","$":"Wind Speed"},{"name":"U","units":"","$":"Max UV Index"},{"name":"W","units":"","$":"Weather Type"},{"name":"Pp","units":"%","$":"Precipitation Probability"}]},
    "DV":{"dataDate":"2012-11-02T07:00:00Z","type":"Forecast","Location":{"i":"310069","lat":"50.7179","lon":"-3.5327","name":"EXETER","country":"ENGLAND","continent":"EUROPE",
    "Period":[{"type":"Day","value":"2012-11-02Z",
    "Rep":[{"D":"SSW","F":"5","G":"18","H":"81","Pp":"45","S":"2","T":"6","V":"EX","W":"13","U":"0","$":"180"},{"D":"SW","F":"3","G":"13","H":"86","Pp":"17","S":"4","T":"5","V":"EX","W":"2","U":"0","$":"360"},{"D":"WSW","F":"5","G":"13","H":"83","Pp":"38","S":"4","T":"6","V":"VG","W":"10","U":"1","$":"540"},{"D":"WSW","F":"7","G":"22","H":"71","Pp":"39","S":"9","T":"9","V":"EX","W":"10","U":"1","$":"720"},{"D":"W","F":"4","G":"40","H":"80","Pp":"64","S":"11","T":"7","V":"VG","W":"14","U":"1","$":"900"},{"D":"WSW","F":"4","G":"18","H":"84","Pp":"35","S":"7","T":"6","V":"VG","W":"9","U":"0","$":"1080"},{"D":"W","F":"4","G":"13","H":"86","Pp":"11","S":"7","T":"6","V":"EX","W":"2","U":"0","$":"1260"}]},{"type":"Day","value":"2012-11-03Z",
    "Rep":[{"D":"S","F":"3","G":"11","H":"89","Pp":"16","S":"4","T":"5","
    Is there some way the the value of a Rep object ($ in the JSON representation) can be used to target the Pp from that report?

    The problem is the value of a Rep object denotes the number of minutes after midnight for that report. Once these have passed the reports are removed. Therefore ...
    Code:
    periods[0].Rep[0];
    would be the 'first' report available but not necessarily the first report for the day.

  4. #4
    Under Construction silver trophybronze trophy AussieJohn's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, Australia
    Posts
    776
    Mentioned
    11 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by jamus View Post
    Sorry. It is definately json. However, I have an extension for Chrome that displays the feed like that and I had just cut and paste it without thinking.
    Ah yesh. I did see were using JSON notation to address the object's properties.

    Quote Originally Posted by jamus View Post
    Is there some way the the value of a Rep object ($ in the JSON representation) can be used to target the Pp from that report?
    When you drill down you can just use the dot-notation to access that property, or if for some reason you need to get a property based on another property then you can also use the bracket-notation to do it that way.

    e.g.
    Code javascript:
    precipitationPercent = periods[0].Rep[0].Pp
    Or
    Code javascript:
    // get the property name from one of the previous objects 
    // let's say that units[9].name contains the string "Pp"
    // based on {"name":"Pp","units":"%","$":"Precipitation Probability"}
     
    precipitationPercent = periods[0].Rep[0][ units[9].name ];

    Hope this helps, not 100% sure if I understood your question correctly, feel free to clarify if I haven't
    var details = {
    . . web: "afterlight.com.au",
    . . photos: "jvdl.id.au",
    . . psa: "usethelatestversion.com"
    }

  5. #5
    SitePoint Addict jamus's Avatar
    Join Date
    Jul 2004
    Location
    Devon, UK
    Posts
    301
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thank you so much - I think I finally got it from your input!

  6. #6
    SitePoint Addict jamus's Avatar
    Join Date
    Jul 2004
    Location
    Devon, UK
    Posts
    301
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Ok. I think Im winning with this now so thank you.

    However, I have another json feed which I can't seem to target items from in the same way. The json looks like this

    Code:
    {
      "Locations":{
        "Location":[{
            "id":"3002",
            "latitude":"60.749",
            "longitude":"-0.854",
            "name":"Baltasound"
          },
          {
            "id":"3005",
            "latitude":"60.139",
            "longitude":"-1.183",
            "name":"Lerwick (S. Screen)"
          },
          {
            "id":"3006",
            "latitude":"60.447",
            "longitude":"-1.277",
            "name":"Sella Ness"
          },
    Im trying this:

    Code:
    function(data) {
    $.each(data.Locations, function(place){
          console.log('location name: '+place.Location.name);
             
        });

    and this

    Code:
    function(data) {
    $.each(data.Locations.Location, function(place){
          console.log('location name: '+place.name);
             
        });
    = but 'cannot read property name of undefined' error.

    What am I doing wrong?

  7. #7
    Under Construction silver trophybronze trophy AussieJohn's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, Australia
    Posts
    776
    Mentioned
    11 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by jamus View Post
    Ok. I think Im winning with this now so thank you.
    Yay, always good to hear

    Quote Originally Posted by jamus View Post
    = but 'cannot read property name of undefined' error.

    What am I doing wrong?
    What happens is that when you put "place" as the parameter for the callback function of the .each() method, it uses that as the key.

    The jQuery.each() callback can be used in 2 different ways, the first is if you pass in the key/value parameters, the second is by using the "this" keyword the current element that is being iterated over.

    In this case, your second example is *almost* done! All you need to do is use "this" instead of "place".

    Code javascript:
    $.each(data.Locations.Location, function(){
        console.log('location name: '+this.name);
    });

    In contrast, the other way would do it is like this:
    Code javascript:
    $.each(data.Locations.Location[0], function(key, val){
        console.log(key, val);
    });

    I purposely used data.Locations.Location[0] here to demo, as this second method is better for looping over objects rather than arrays. You *can* use that method as well to loop over arrays of course, the key will then be the array index and val will be the value of the item at that index in the array. However, when I know that I'm looping over an array I tend to use the first method as all I'm usually interested in the value.
    var details = {
    . . web: "afterlight.com.au",
    . . photos: "jvdl.id.au",
    . . psa: "usethelatestversion.com"
    }

  8. #8
    SitePoint Addict jamus's Avatar
    Join Date
    Jul 2004
    Location
    Devon, UK
    Posts
    301
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Wow. Thank you.

    I'll give that a try.

    Would you ever have an array stored in a object? How would I tell them apart in the json feed? Sorry if that's an obvious question!

  9. #9
    Under Construction silver trophybronze trophy AussieJohn's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, Australia
    Posts
    776
    Mentioned
    11 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by jamus View Post
    Wow. Thank you.

    I'll give that a try.

    Would you ever have an array stored in a object? How would I tell them apart in the json feed? Sorry if that's an obvious question!
    I guess normally, since you'd be processing the data somehow, you would know which nodes are objects and which are arrays. Though, strictly speaking if you're using the $.each() method you don't *need* to know whether you're iterating over an array or an object.

    Of course you can inspect the JSON object in your debugger (Dev tools, firebug, whatever) to see which nodes are what.

    The actual question of whether you could/should/would store an array in an object, it all comes down to "what" the data is. Let me illustrate this in code:

    Code javascript:
    var someObject = {
     
        "title": "Some string",
     
        "messages": [ //messages is a list of "something", so it's in an array
     
            // a "message" consists of "content" and an "id" - so an object would be better to represent this.
            { 
               "content": "Hello", 
               "id": 1
            },
            {
               "content": "World",
               "id": 2
            }
        ]
     
    };
    var details = {
    . . web: "afterlight.com.au",
    . . photos: "jvdl.id.au",
    . . psa: "usethelatestversion.com"
    }

  10. #10
    SitePoint Addict jamus's Avatar
    Join Date
    Jul 2004
    Location
    Devon, UK
    Posts
    301
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thank you!

    Your suggestion worked and I can now get the locations.

    But better than that I think I've actually got a handle on it. Until the next time I'm left scratching my head that is.

    Thank you for your time to explain.


Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •