3

As in topic, I'm trying to parse this json data in to my QML project

link: http://www.rad.io/info/menu/valuesofcategory?category=_genre

So I have list of 188 elements but don't know how to get value of each element...

here is a link to JSONListModel component I used in this example

here is qml code:

import QtQuick 2.0
import Ubuntu.Components 1.1
import "../components"
import Ubuntu.Components.ListItems 1.0 as ListItem


Page {
    title: i18n.tr("by Genre")


    JSONListModel {
        id: json
        source: "http://www.rad.io/info/menu/valuesofcategory?category=_genre"
        query: "$"
    }


    UbuntuListView {
        height: parent.height
        width: parent.width
        clip: true
        model: json.model
        cacheBuffer: contentHeight


        delegate: ListItem.Standard {
            text: index + "  " + indexValue
        }

    }    

}
1
  • How about a XHR function that returns the json data. And in the listview you can just use modelData.property, it will automatically do it by index I think Nov 22, 2014 at 5:43

2 Answers 2

5

I'm no expert on JSONListModel so I may be mistaken, but it seems to be expecting to iterate over a list of Objects. What you get from rad.io is a list of strings, which seems to be causing your problems. But since you don't need to do any fancy processing of the result, it's easy to roll this by hand.

What you want to do is parse the response into a list (usingJSON.parse). Then you can go through the elements of the list. For each, you create an object and append that to a ListModel. Note that the ListModel takes objects, not strings. Then the delegate can reference the properties of those objects.

Example code:

import QtQuick 2.0
import Ubuntu.Components 1.1
import Ubuntu.Components.ListItems 1.0 as ListItem

MainView {
    width: 300
    height: 600
    property string source: "http://www.rad.io/info/menu/valuesofcategory?category=_genre"

    ListModel {
        id: listModel
    }

    Component.onCompleted: {
        var xhr = new XMLHttpRequest;
        xhr.open("GET", source);
        xhr.onreadystatechange = function() {
            if (xhr.readyState == XMLHttpRequest.DONE) {
                var list = JSON.parse(xhr.responseText);
                listModel.clear();
                for (var i in list)
                    listModel.append({ "genre": list[i] });
            }
        }
        xhr.send();
    }

    Page {
        title: i18n.tr("by Genre")

        UbuntuListView {
            height: parent.height
            width: parent.width
            clip: true
            model: listModel
            cacheBuffer: contentHeight

            delegate: ListItem.Standard {
                text: index + "  " + genre
            }
        }
    }
}

Let me take a moment to remind you of the importance of posting short, self-contained, correct examples. The code you posted failed to run not because of any problem with parsing JSON, but because a Tab cannot be a top-level widget. Anyone who tried to help you first had to figure out that before getting to the real problem.

Also, when using a non-default component, like JSONListModel, please note this fact and point us to where it can be found. The less work it takes to reproduce the problem, the better.

1
  • I'll make sure I post working code next time and all components used in it too. Your answer seams to be the best one. I actually manage to achieve the same effect by editing JSONListModel component a bit... but your solution seams to be less memory consuming. Thanks
    – Majster-pl
    Nov 22, 2014 at 21:54
3

Actually no data is stored in your ListModel.

I suppose you are using this, from GitHub.

JSONListModel is filled by using the method append(jsobject dict) from QtQuick ListModel. This method requires a role and a value to be specified, but the json data you get from rad.io contains only the values.

For that reason, ListElements are added in your model, but they don't contain any data. You can check this, by adding the following lines in your delegate:

Component.onCompleted: {
    console.log(JSON.stringify(json.model.get(model.index)))
}

I'd suggest you to read the content of the json file you download from the web, using XMLHttpRequest, and then parse it and add its content to a string list (or a var). You will be able to access the content through a ListView, using the modelData role.

1
  • See Robert's answer that provides a working snippet of code for the suggested solution (Component.onCompleted signal).
    – user323695
    Nov 22, 2014 at 7:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .