2
votes

The following code the constructor loads up a Qml file that loads data from a remote Json data source and this works perfectly fine. When I call the startMenu method I am using the exact same Qml in MainMenu.Qml but as soon as I call dataSource.load() my application crashes at QDeclarativeExpression::hasError (), after which it just hangs. There are no error messages or exceptions being emitted.

If I move the dataSource.load(); to a button click it works, but then I have no way to load my data when the page loads.

#include "MyAppBB.hpp"

#include <bb/cascades/Application>
#include <bb/cascades/QmlDocument>
#include <bb/cascades/AbstractPane>
#include <bb/cascades/Button>
#include <bb/data/DataSource>
#include <wifi/wifi_service.h>

using namespace bb::cascades;

MyAppBB::MyAppBB(bb::cascades::Application *app) :
        QObject(app) {
    // create scene document from main.qml asset
    // set parent to created document to ensure it exists for the whole application lifetime
    bb::data::DataSource::registerQmlTypes();
    QmlDocument *qml = QmlDocument::create("asset:///main.qml").parent(this);
    this->myApp = app;

    QDeclarativePropertyMap* propertyMap = new QDeclarativePropertyMap;
    propertyMap->insert("name", QVariant(QString("Wes Barichak")));
    propertyMap->insert("phone", QVariant(QString("519-555-0199")));

    // create root object for the UI
    this->root = qml->createRootObject<AbstractPane>();

    qml->setContextProperty("propertyMap", propertyMap);
    qml->setContextProperty("root", this);

    QObject *newButton = root->findChild<QObject*>("btnLogin");
    QObject::connect(newButton, SIGNAL(clicked()), this, SLOT(loginClick()));
    // set created root object as a scene
    app->setScene(root);
}

void MyAppBB::startMenu() {
    QmlDocument *qml2 = QmlDocument::create("asset:///MainMenu.qml").parent(this);
    AbstractPane *root2 = qml2->createRootObject<AbstractPane>();

    this->myApp->setScene(root2);
}

Here is the Qml

import bb.cascades 1.0
import bb.data 1.0

Page {
    Container {
        layout: StackLayout {
        }


        TextField {
            id: txtUsername
        }

        ListView {
            id: myListView

            // Associate the list view with the data model that's defined in the
            // attachedObjects list
            dataModel: dataModel
            listItemComponents: [
                ListItemComponent {
                    type: "item"

                    // Use a standard list item to display the data in the data
                    // model
                    StandardListItem {

                        title: ListItemData.identificationType
                        description: ListItemData.identificationTypeId
                    }
                }
            ]
        }
        attachedObjects: [
            GroupDataModel {
                id: dataModel

                // Sort the data in the data model by the "pubDate" field, in
                // descending order, without any automatic grouping
                sortingKeys: [
                    "ID"
                ]
                sortedAscending: false
                grouping: ItemGrouping.None
            },
            DataSource {
                id: dataSource

                source: "http://192.168.150.1/JsonMobileApiService/Service1.svc/GetIDTypes"

                type: DataSourceType.Json
                onDataLoaded: {
                    dataModel.clear();
                    dataModel.insertList(data);
                }
            }
        ]
        onCreationCompleted: {
            txtUsername.setText("boo!");
            // Statement below causes crash
            dataSource.load();
        }
    }
}
1

1 Answers

2
votes

There is an onCreationCompleted slot in AbstractPane, you can use that to call load.

Its in the API spec for the XMLDataAccess as an example. I'm using this to load data from an XML file myself, it works

  import bb.cascades 1.0
  import bb.data 1.0
  Page {
  content: ListView {
    id: listView
    dataModel: dataModel
    ...
  }
  attachedObjects: [
    GroupDataModel {
      id: dataModel
    },
    DataSource {
      id: dataSource
      source: "contacts.xml"
      query: "/contacts/contact"
      onDataLoaded: {
        dataModel.insertList(data);
      }
    }
  ]
  onCreationCompleted: { dataSource.load(); }
}