Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Native Development

Reply
Developer
HuXu77
Posts: 195
Registered: ‎02-10-2011
My Device: Playbook 16GB and Z10
My Carrier: Verizon
Accepted Solution

JsonDataAccess bug?

[ Edited ]

I am trying to parse this:

 

{
    "activities":[
        {
            "activityId":<value>,
        },
       <..>
    ],
    "goals":{
        "activeScore":<value>,
    },
    "summary":{
        "distances":[
            {"activity":"tracker", "distance":<value>},
            {"activity":"loggedActivities", "distance":<value>},
            <..>
        ],
        "elevation":<value>,
        "veryActiveMinutes":<value>
    }
}

 

And this is my code:

 

void ApiResponse::parse(QByteArray data) {
	JsonDataAccess jda(new QObject);
	QVariant resp = jda.loadFromBuffer(data);
	if (resp.canConvert(QVariant::List)) {
		foreach(const QVariant &var, resp.toList()) {
			qDebug() << var;
		}
	} else if (response != NULL && resp.canConvert(QVariant::Map)) {
		response->parse(resp.toMap());
	}
}

 

So I am expecting to get a Map that has "activities", "goals" and "summary" but I am only getting "activities".  I verified this by placing a break point at the very begining of the parse method.

 

breakpoint 

Is there something I am missing to get it to get the other objects?

 

Edit: Also after trying to debug some more I noticed that when I opened up 'resp' I see this:

 

resp

 

The data has char 112 'p', well when I open up the QByteArray and copy its values to notepad++, I see two places that match 112 'p', char 84 and char 558.  Could this mean it stopped parsing at either of those two points?  A memory issue?

_________________________________________________
Apps
Go Music
Flashlight Fast Free/Pro
Fitbit for BlackBerry PlayBook
Please use plain text.
BlackBerry Development Advisor (Retired)
smacmartin
Posts: 499
Registered: ‎05-07-2012
My Device: developer
My Carrier: developer

Re: JsonDataAccess bug?

What is response, and what is response->parse() calling?

 

Stuart

Please use plain text.
Developer
HuXu77
Posts: 195
Registered: ‎02-10-2011
My Device: Playbook 16GB and Z10
My Carrier: Verizon

Re: JsonDataAccess bug?

[ Edited ]

Response = Activity class

Where the parse method:

 

void Activities::parse(QVariantMap qMap) {
	QVariantMap summaryMap = qMap["summary"].toMap();
	setActiveScore(summaryMap["activeScore"].toString());
	setSteps(summaryMap["steps"].toString());
}

 

I placed my break point on "QVariantMap summaryMap = qMap["summary"].toMap();"

 

Edit: Ignore the sets, I removed lots of data from the example data set, to make it easier to see the structure, which included the steps and activeScore from summary.

_________________________________________________
Apps
Go Music
Flashlight Fast Free/Pro
Fitbit for BlackBerry PlayBook
Please use plain text.
BlackBerry Development Advisor (Retired)
smacmartin
Posts: 499
Registered: ‎05-07-2012
My Device: developer
My Carrier: developer

Re: JsonDataAccess bug?

[ Edited ]

I expect it's the way you're interpreting the lists (activities, distances) vs. maps (goals, summaries).

My second suspicion is recursion: are you recursing, and only on the first item you see?  (I don't have your full code so can't see if there's a bug there)

 

I constructed a similar example from your sketch, and loaded it from a json file but that should give same result as starting with an array (although if we still can't track down your issue we could play further there).

 

You don't show your full handling or your full json.  For my code, I get the flip behaviour, as I expect, based on how I'm interpreting the code. Activities contains a list, goals and summary contain a map.   The code that uses the VariantList really should have defensive code checking the type: it's otherwise hard to tell the difference between "that's not a map" and "that a map with nothing in it".

 

Here's my sample json, handling routine, and debug output:

 

 

================

json:

{
    "activities": [
        {
            "activityId": "anId"
        }
    ],
    "goals":{
        "activeScore": "anActiveScore"
    },
    "summary": {
        "distances": [
            {"activity": "tracker", "distance": "distance1"},
            {"activity": "loggedActivities", "distance": "distance2"}
        ],
        "elevation": "myElevation",
        "veryActiveMinutes": "vam"
    }
}

=====

code...

void parseMe(QVariantMap qMap) {
    QVariantMap summaryMap = qMap["summary"].toMap();
    QVariantMap goalsMap   = qMap["goals"].toMap();
    QVariantMap activities = qMap["activities"].toMap();
    QVariantMap notThere   = qMap["notThere"].toMap();

    if (summaryMap.isEmpty())
        qDebug() << "Summmary map is empty";
    if (goalsMap.isEmpty())
        qDebug() << "goals map is empty";
    if (activities.isEmpty())
        qDebug() << "activities map is empty";
    if (notThere.isEmpty())
        qDebug() << "notThere map is empty";
}

void parseMe() {

    JsonDataAccess jda("app/native/assets/my.json");
    QVariant resp = jda.load();
    //JsonDataAccess jda(new QObject);
    //QByteArray buffer = data1.toAscii();
    //QVariant resp = jda.loadFromBuffer(buffer);
    if (resp.canConvert(QVariant::List)) {
        foreach(const QVariant &var, resp.toList()) {
            qDebug() << var;
        }
    } else if (resp.canConvert(QVariant::Map)) {
        parseMe(resp.toMap());
    }
}

HelloCascadesApp::HelloCascadesApp()
{
    // Here we create a QMLDocument and load it, we are using build patterns.
    QmlDocument *qml = QmlDocument::create().load("hellocascades.qml");

    if (!qml->hasErrors()) {

        // The application Page is created from QML.
        Page *appPage = qml->createRootNode<Page>();

        if (appPage) {
            // Finally the main scene for the application is set the Page.
            Application::setScene(appPage);
        }
        parseMe();

    }
}
=========

output:

activities map is empty
notThere map is empty

 

Stuart

 

Please use plain text.
BlackBerry Development Advisor (Retired)
smacmartin
Posts: 499
Registered: ‎05-07-2012
My Device: developer
My Carrier: developer

Re: JsonDataAccess bug?

[ Edited ]

Actually, my suspicions of my previous post perhaps don't match the symptoms.

More likely is the buffer you are passing is malformed in some way, resulting in only the one item read.

Can you try loading from a test json file and see if that works.

If it does, then try from a buffer with the same contents;

otherwise, make a really simple json file of the most trivial case and see if that works, and build up from there til you find the offending condition.

(Then let me know if that was it!)

 

Stuart

Please use plain text.
Developer
HuXu77
Posts: 195
Registered: ‎02-10-2011
My Device: Playbook 16GB and Z10
My Carrier: Verizon

Re: JsonDataAccess bug?

[ Edited ]

Ok, I printed out the QString version of the QByteArray, added to a file (the exact, unmodified results) and I am still only getting "activities".

 

Edit, actually, when I break point on it, it doesn't show it, but if I look at the value after I grab for it, its there!  Strange that I can't see it when looking in the Variables view.  And the reason I thought it wasn't happening is because I had in my QML a label with text: "Total Active Score: "+activities.activeScore and it was turning up undefined, and it was showing up undefined because I have another component labeled activities at the same time I was trying to bind a q_object to that label.  It works now, thank you!

  

See what you get with this:

 

{
	"activities":[]
	,"goals":
		{"activeScore":1000,
		"caloriesOut":2184,
		"distance":8.05,
		"steps":10000}
	,"summary":
		{"activeScore":1,
			"activityCalories":0,
			"caloriesOut":1618,
			"distances":[
				{"activity":"total","distance":0}
				,{"activity":"tracker","distance":0}
				,{"activity":"loggedActivities","distance":0}
				,{"activity":"veryActive","distance":0}
				,{"activity":"moderatelyActive","distance":0}
				,{"activity":"lightlyActive","distance":0}
				,{"activity":"sedentaryActive","distance":0}
			]
			,"fairlyActiveMinutes":0
			,"lightlyActiveMinutes":0
			,"marginalCalories":0
			,"sedentaryMinutes":945
			,"steps":0
			,"veryActiveMinutes":0
		}
}

 

Edit: My guess is that its either a problem with activities being empty or the fact that the values aren't strings.  Just looking at the difference between your example json and mine.

_________________________________________________
Apps
Go Music
Flashlight Fast Free/Pro
Fitbit for BlackBerry PlayBook
Please use plain text.