Android Question json help

tufanv

Expert
Licensed User
Longtime User
Hello

I have a json retrieved from remote web
B4X:
{"time":{"updated":"Dec 19, 2016 12:30:00 UTC","updatedISO":"2016-12-19T12:30:00+00:00","updateduk":"Dec 19, 2016 at 12:30 GMT"},"bpi":{"USD":{"code":"USD","rate":"791.3488","description":"United States Dollar","rate_float":791.3488},"TRY":{"code":"TRY","rate":"2,770.3276","description":"Turkish Lira","rate_float":2770.3276}}}

I got this with httpjob and used the code below :
B4X:
Dim parser As JSONParser
parser.Initialize(res)
dim m as map = parser.nextobject

log m gives me :

B4X:
    time = "(read only map) {\n    updated = \"Dec 19, 2016 12:34:00 UTC\";\n    updatedISO = \"2016-12-19T12:34:00+00:00\";\n    updateduk = \"Dec 19, 2016 at 12:34 GMT\";\n}";
}
{"time":{"updated":"Dec 19, 2016 12:34:00 UTC","updatedISO":"2016-12-19T12:34:00+00:00","updateduk":"Dec 19, 2016 at 12:34 GMT"},"bpi":{"USD":{"code":"USD","rate":"791.0175","description":"United States Dollar","rate_float":791.0175},"TRY":{"code":"TRY","rate":"2,770.3276","description":"Turkish Lira","rate_float":2770.3276}}}
code":"TRY","rate":"2,770.3276","description"

How can i retrieve the "rate_float" from this map ? m.get("rate_float") is not working.

TY
 

DonManfred

Expert
Licensed User
Longtime User
B4X:
Dim parser As JSONParser
parser.Initialize(<text>)
Dim root As Map = parser.NextObject
Dim bpi As Map = root.Get("bpi")
Dim USD As Map = bpi.Get("USD")
Dim rate_float As Double = USD.Get("rate_float")
Dim code As String = USD.Get("code")
Dim rate As String = USD.Get("rate")
Dim description As String = USD.Get("description")
Dim mytry As Map = bpi.Get("TRY")
Dim rate_float As Double = mytry.Get("rate_float")
Dim code As String = mytry.Get("code")
Dim rate As String = mytry.Get("rate")
Dim description As String = mytry.Get("description")
Dim time As Map = root.Get("time")
Dim updateduk As String = time.Get("updateduk")
Dim updatedISO As String = time.Get("updatedISO")
Dim updated As String = time.Get("updated")
 
Upvote 0

tufanv

Expert
Licensed User
Longtime User
B4X:
Dim parser As JSONParser
parser.Initialize(<text>)
Dim root As Map = parser.NextObject
Dim bpi As Map = root.Get("bpi")
Dim USD As Map = bpi.Get("USD")
Dim rate_float As Double = USD.Get("rate_float")
Dim code As String = USD.Get("code")
Dim rate As String = USD.Get("rate")
Dim description As String = USD.Get("description")
Dim mytry As Map = bpi.Get("TRY")
Dim rate_float As Double = mytry.Get("rate_float")
Dim code As String = mytry.Get("code")
Dim rate As String = mytry.Get("rate")
Dim description As String = mytry.Get("description")
Dim time As Map = root.Get("time")
Dim updateduk As String = time.Get("updateduk")
Dim updatedISO As String = time.Get("updatedISO")
Dim updated As String = time.Get("updated")

Dear Donmanfred ,
Couldnt have been better ! Thanks very mu8ch
 
Upvote 0

tufanv

Expert
Licensed User
Longtime User
B4X:
Dim parser As JSONParser
parser.Initialize(<text>)
Dim root As Map = parser.NextObject
Dim bpi As Map = root.Get("bpi")
Dim USD As Map = bpi.Get("USD")
Dim rate_float As Double = USD.Get("rate_float")
Dim code As String = USD.Get("code")
Dim rate As String = USD.Get("rate")
Dim description As String = USD.Get("description")
Dim mytry As Map = bpi.Get("TRY")
Dim rate_float As Double = mytry.Get("rate_float")
Dim code As String = mytry.Get("code")
Dim rate As String = mytry.Get("rate")
Dim description As String = mytry.Get("description")
Dim time As Map = root.Get("time")
Dim updateduk As String = time.Get("updateduk")
Dim updatedISO As String = time.Get("updatedISO")
Dim updated As String = time.Get("updated")

by the way is it possible to get the price of date as the date is changing everyday: I mean this is the json :
B4X:
{"bpi":{"2016-12-18":2760.045},"disclaimer":"This data was produced from the CoinDesk Bitcoin Price Index. BPI value data returned as TRY.","time":{"updated":"Dec 19, 2016 00:03:00 UTC","updatedISO":"2016-12-19T00:03:00+00:00"}}

2016-12-18 is the yesterdays date . but the date changes everyday so tonorrow the json will be :

B4X:
{"bpi":{"2016-12-19":2760.045},"disclaimer":"This data was produced from the CoinDesk Bitcoin Price Index. BPI value data returned as TRY.","time":{"updated":"Dec 19, 2016 00:03:00 UTC","updatedISO":"2016-12-19T00:03:00+00:00"}}

so to get 2760.045 i must find another way . i tried :

B4X:
            Dim Yesterday As Long
            Yesterday = DateTime.add(DateTime.Now, 0, 0, -1)

            DateTime.DateFormat = "yyyy-MM-dd"
            Dim tarih As String = Yesterday
            Log (DateTime.Date(Yesterday))
            Dim oldprice As String =bpi.Get(tarih)
            Log(oldprice)

this gives me null altough the tarih is "2016-12-18" just like in the json. Where am i wrong at this ?
 
Upvote 0

tufanv

Expert
Licensed User
Longtime User
ah i was wrong at tarih date
i changed it to
Dim tarih As String = DateTime.Date(Yesterday)
and it is ok now! Thanks !
 
Upvote 0

tufanv

Expert
Licensed User
Longtime User
I have another question about this. Another website api gives the data not in json but like this :

B4X:
[
    {
        "symbol": "BTC",
        "rank": "1",
        "price_usd": "791.445",
        "price_btc": "1.0",
        "24h_volume_usd": "64509000.0",
        "market_cap_usd": "12704066990.0",
        "available_supply": "16051737.0",
        "total_supply": "16051737.0",
        "percent_change_1h": "-0.17",
        "percent_change_24h": "0.21",
        "percent_change_7d": "1.44",
        "last_updated": "1482154472"
    }
]

i cant load this into directly map and i cant use json as this is not json. How can i use this most efffectively. This is like a map but it is not. I cant load this into a map.
 
Upvote 0

KMatle

Expert
Licensed User
Longtime User
Generally:

[ = List
{ = Map

"x": "y" = Key/Value pair inside a map

{{ = map in a map

So {Mymap:{"Name":"Klaus","Age":"48"}}

is a Map which contains a Map with two entries (following the rule { = Map)

This is a list of two maps (see the [ for a list)

[{Mymap1:{"Name":"Klaus","Age":"48"}},{Mymap2:{"Name":"Klaus","Age":"48"}}]
 
Upvote 0

tufanv

Expert
Licensed User
Longtime User
It's Erel's :) But I'm lazy so I know that little helpers :)
Yes it is a very good tool. I have one more question. I have a data like this :

B4X:
{"bpi":{"2016-11-19":2529.4387,"2016-11-20":2457.4058,"2016-11-21":2476.4122,"2016-11-22":2530.4663,"2016-11-23":2513.7142,"2016-11-24":2531.443,"2016-11-25":2542.4719,"2016-11-26":2529.0364,"2016-11-27":2510.9517,"2016-11-28":2504.2451,"2016-11-29":2497.8719,"2016-11-30":2546.3946,"2016-12-01":2625.2549,"2016-12-02":2706.7649,"2016-12-03":2690.9782,"2016-12-04":2700.1562,"2016-12-05":2644.3883,"2016-12-06":2626.8372,"2016-12-07":2605.1403,"2016-12-08":2634.9333,"2016-12-09":2668.2762,"2016-12-10":2687.8108,"2016-12-11":2680.393,"2016-12-12":2702.0001,"2016-12-13":2708.1274,"2016-12-14":2735.3231,"2016-12-15":2716.8577,"2016-12-16":2739.7886,"2016-12-17":2763.9442,"2016-12-18":2760.045,"2016-12-19":2792.4361}}

the keys are dynamic so i cant use m.get(date) like things to get the value. Is there a way to get only the values because keys will be changing everyday.
 
Upvote 0

tufanv

Expert
Licensed User
Longtime User
You need to learn how the json look like and parse it yourself.
get the root map/list and work with it yourself to find all items.

yeah i did that and i have a different problem. I extracted the map with json parse and i used map.values to list all values but they are not ordered as they are in the map.first portion shows the map and it starts with 2529.4387 but when i use map.values it is in a total different sequence. Yes i can find a way to get them one by one but there must be a easier way for this.
B4X:
(read only map) {
    "2016-11-19" = "2529.4387";
    "2016-11-20" = "2457.4058";
    "2016-11-21" = "2476.4122";
    "2016-11-22" = "2530.4663";
    "2016-11-23" = "2513.7142";
    "2016-11-24" = "2531.443";
    "2016-11-25" = "2542.4719";
    "2016-11-26" = "2529.0364";
    "2016-11-27" = "2510.9517";
    "2016-11-28" = "2504.2451";
    "2016-11-29" = "2497.8719";
    "2016-11-30" = "2546.3946";
    "2016-12-01" = "2625.2549";
    "2016-12-02" = "2706.7649";
    "2016-12-03" = "2690.9782";
    "2016-12-04" = "2700.1562";
    "2016-12-05" = "2644.3883";
    "2016-12-06" = "2626.8372";
    "2016-12-07" = "2605.1403";
    "2016-12-08" = "2634.9333";
    "2016-12-09" = "2668.2762";
    "2016-12-10" = "2687.8108";
    "2016-12-11" = "2680.393";
    "2016-12-12" = "2702.0001";
    "2016-12-13" = "2708.1274";
    "2016-12-14" = "2735.3231";
    "2016-12-15" = "2716.8577";
    "2016-12-16" = "2739.7886";
    "2016-12-17" = "2763.9442";
    "2016-12-18" = "2760.045";
    "2016-12-19" = "2792.4361";
}
<B4IList: (
    "2687.8108",
    "2680.393",
    "2702.0001",
    "2708.1274",
    "2735.3231",
    "2716.8577",
    "2739.7886",
    "2763.9442",
    "2760.045",
    "2792.4361",
    "2529.4387",
    "2457.4058",
    "2476.4122",
    "2530.4663",
    "2513.7142",
    "2531.443",
    "2542.4719",
    "2529.0364",
    "2510.9517",
    "2504.2451",
    "2497.8719",
    "2546.3946",
    "2625.2549",
    "2706.7649",
    "2690.9782",
    "2700.1562",
    "2644.3883",
    "2626.8372",
    "2605.1403",
    "2634.9333",
    "2668.2762"
)>
 
Upvote 0

tufanv

Expert
Licensed User
Longtime User
in case someone needs in the future , I solved id with the code below :

B4X:
            Dim parser As JSONParser
            parser.Initialize(res)
            Dim root3 As Map = parser.NextObject
            Dim bpi As Map = root3.Get("bpi")
            For i=30 To 1 Step-1
                Dim Yesterday As Long
           
                Yesterday = DateTime.add(DateTime.Now, 0, 0, -i)

                DateTime.DateFormat = "yyyy-MM-dd"
                Dim tarih As String = DateTime.Date(Yesterday)
                Log(bpi.Get(tarih))
            Next
 
Upvote 0

KMatle

Expert
Licensed User
Longtime User
{"bpi":{"2016-11-19":2529.4387,"2016-11-20":2457.4058,"2016-11-21":2476.4122,"2016-11-22":2530.4663,"2016-11-23":2513.7142,"2016-11-24":2531.443,"2016-11-25":2542.4719,"2016-11-26":2529.0364,"2016-11-27":2510.9517,"2016-11-28":2504.2451,"2016-11-29":2497.8719,"2016-11-30":2546.3946,"2016-12-01":2625.2549,"2016-12-02":2706.7649,"2016-12-03":2690.9782,"2016-12-04":2700.1562,"2016-12-05":2644.3883,"2016-12-06":2626.8372,"2016-12-07":2605.1403,"2016-12-08":2634.9333,"2016-12-09":2668.2762,"2016-12-10":2687.8108,"2016-12-11":2680.393,"2016-12-12":2702.0001,"2016-12-13":2708.1274,"2016-12-14":2735.3231,"2016-12-15":2716.8577,"2016-12-16":2739.7886,"2016-12-17":2763.9442,"2016-12-18":2760.045,"2016-12-19":2792.4361}}

This is just a map inside a map -> brackets {} = maps. So let's follow this thought:

A map contains a key/value pair. Both are delimited by a ":". So guess what the key and the value is? (Hint: Key is "bpi" and value everything behind the ":").

So if "everything behing the : is the value" is true. What is the content of the value then? It starts with a bracket. Following the simple rule it MUST be a map.
Let's check that:

1. Does it start with a {? Yes!
2. What do we know? It must be a map.
3. Is it a map? Yes, because it has key/value fields delimited by ":"

So the value of the key "bpi" is another map! Maps can contain almost enything, even maps as a value.

Let's check if we find the corresponding code:

B4X:
Dim JustAString As String = $"{"bpi":{"2016-11-19":2529.4387,"2016-11-20":2457.4058,"2016-11-21":2476.4122,"2016-11-22":2530.4663,"2016-11-23":2513.7142,"2016-11-24":2531.443,"2016-11-25":2542.4719,"2016-11-26":2529.0364,"2016-11-27":2510.9517,"2016-11-28":2504.2451,"2016-11-29":2497.8719,"2016-11-30":2546.3946,"2016-12-01":2625.2549,"2016-12-02":2706.7649,"2016-12-03":2690.9782,"2016-12-04":2700.1562,"2016-12-05":2644.3883,"2016-12-06":2626.8372,"2016-12-07":2605.1403,"2016-12-08":2634.9333,"2016-12-09":2668.2762,"2016-12-10":2687.8108,"2016-12-11":2680.393,"2016-12-12":2702.0001,"2016-12-13":2708.1274,"2016-12-14":2735.3231,"2016-12-15":2716.8577,"2016-12-16":2739.7886,"2016-12-17":2763.9442,"2016-12-18":2760.045,"2016-12-19":2792.4361}}"$
    Log(JustAString)
  
    Dim parser As JSONParser
    parser.Initialize(JustAString)
  
    Dim MainMap, MapInTheMap As Map
    MainMap=parser.Nextobject
    Log(MainMap.Get("bpi"))
    MapInTheMap=MainMap.Get("bpi")

1. First it's just a string (which will be returned from f.e. a Job)
2. Let's initialize the parser with it and get the next object and put it in a map
3. Again: Why does he know that the whole thing must be a map? (Hint: I took a look at the string and... You know the answer)
4. Now I know that the key is bpi and the value must be a map, too (everything behind the : is the va....)
5 Let's get it by the key "bpi" and put it in a map (because it is one)

Unbenannt.JPG


What if....

The whole thing starts with a [ ? Hm... Looks like a list. So put it in a list. Can lists contain maps? Of course!

:)
 
Upvote 0
Top