2

I am try to navigate page after parsing but before i got response from server, method getLoginData() is called from Qml file and get false because at the time of calling this function response not get from server, when i click again in button where this function is call, i got accurate result because this time i already got the result. so please help me to solve it out.......

My code...

[B]main.qml[/B]

    enter code here

// Navigation pane project template
import bb.cascades 1.0
import bb.system 1.0

NavigationPane {
    id: navigationPane
    objectName: "navigationPaneQml"
    Page {
        id: loginPage
        objectName : "pageQml"
        Container {
            id: container1
            background: Color.Green
            leftPadding: 10
            rightPadding: 10
            topPadding: 10
            layout: StackLayout {
                orientation:LayoutOrientation.TopToBottom       
            }
            TextField {
                id: usernameBox
                objectName: "textFieldRetrived"
                hintText: "Enter Your Mobile Number"
                topPadding: 10
                inputMode: TextFieldInputMode.PhoneNumber
                preferredWidth: maxWidth
                input {
                    flags: TextInputFlag.PredictionOff |
TextInputFlag.AutoCorrectionOff
                }
                //                validator: IntValidator {
                //                    bottom: 0
                //                    top: 9999999999
                //                }
                validator: Validator {
                    mode: ValidationMode.Immediate
                    errorMessage: "Your username must be 10 characters."
                    onValidate: {
                        if (usernameBox.text.length < 10 || usernameBox.text.length > 10) state = ValidationState.Invalid;
                        else state = ValidationState.Valid;
                    }
                }

                //                validator: RegExpValidator {
                //                    mode: ValidationMode.Immediate
                //                    regExp: /\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/
                //                    onValidate: {
                //                        if (usernameBox.text.length <= 10) state = ValidationState.Valid;
                //                        else state = ValidationState.Invalid;
                //                    }
                //                }

            }
            Button {
                id: submitButton
                objectName : submitButtonQml
                horizontalAlignment: HorizontalAlignment.Center
                //                verticalAlignment: VerticalAlignment.Center
                text: qsTr("Submit")
                preferredWidth: minWidth
                //                imageSource: "asset:///images/picture1thumb.png"

                attachedObjects: [
                    SystemToast {
                        id: invalidUsername
                        body: "Invalid Username"
                        onFinished: {
                            //                                Application.quit();
                        }
                    },
                    SystemToast {
                        id: networkNotAvalable
                        body: "Network not Avalable"
                        onFinished: {
                            //                                Application.quit();
                        }
                    },
                    SystemToast {
                        id: invalidToast
                        body: "Not a valid input"
                        onFinished: {
                            //                                Application.quit();
                        }
                    },
                    ComponentDefinition {
                        id: pageDefinition
                        source: "splash.qml"
                    }
                ]
                onClicked: {
                    if(usernameBox.text!= null && usernameBox.text!=""){
                        if(app.isNetworkAvailable()){
                            app.initiateRequest(usernameBox.text)

                            if (app.getLoginData() == "True"){
                                var newPage = pageDefinition.createObject();
                                navigationPane.push(newPage);
                            }else{
                                invalidUsername.show()
                            }
                        }else {
                            networkNotAvalable.show()
                        }
                    }else{
                        invalidToast.show()
                    }

                }
            }
            TextArea {
                id: chat
                objectName: "textArea"
                inputMode: TextAreaInputMode.Default
            }

            Container {
                id: cntrUpdates
                horizontalAlignment: HorizontalAlignment.Center
                //                       verticalAlignment: VerticalAlignment.Top
                layout: StackLayout {
                    orientation: LayoutOrientation.LeftToRight
                }
                preferredWidth: 1280.0
                leftPadding: 90.0
                topPadding: 20.0
                Label {
                    objectName: "lblRetrieve"
                    text: "Retrieving contact list ..."
                    textStyle.textAlign: TextAlign.Right
                    verticalAlignment: VerticalAlignment.Center
                }
                // The activity indicator has an object name set so that
                // we can start and stop it from C++ code.
                ActivityIndicator {
                    objectName: "indicator"
                    running: false
                }
            } 
        }

    }
    onCreationCompleted: {
        // this slot is called when declarative scene is created
        // write post creation initialization here
        console.log("NavigationPane - onCreationCompleted()");

        // enable layout to adapt to the device rotation
        // don't forget to enable screen rotation in bar-bescriptor.xml (Application->Orientation->Auto-orient)
        OrientationSupport.supportedDisplayOrientation = SupportedDisplayOrientation.All;
    }
}


[B]DemoProject2.cpp[/B]

// Navigation pane project template
#include "DemoProject2.hpp"

#include <bb/cascades/Application>
#include <bb/cascades/QmlDocument>
#include <bb/cascades/AbstractPane>

#include <QIODevice>

#include <bb/cascades/XmlDataModel>
#include <bb/cascades/Color>

#include <bps/bps.h>
#include <bps/netstatus.h>
#include <bps/locale.h>

#include <QXmlStreamReader>

#include <QFile>
#include <QDir>
#include <QDebug>
#include <iostream>
#include <QtCore/QCoreApplication>
#include <QTextStream>
#include <QDomDocument>
#include <QDomNodeList>
#include <QtXml/qxml.h>
#include <QString>
#include <bb/cascades/ValidationMode>
#include <bb/cascades/Validator>
#include <bb/system/SystemToast>
#include <bb/system/SystemUiPosition>
#include <QtCore/QDebug>

using namespace bb::cascades;
using namespace bb::system;

DemoProject2::DemoProject2(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
    QmlDocument *qml = QmlDocument::create("asset:///main.qml").parent(this);

    // Expose this class to QML so that we can call it's functions from C++ code.
    qml->setContextProperty("app", this);

    // create root object for the UI
    AbstractPane *root = qml->createRootObject<AbstractPane>();
    // set created root object as a scene




    // Retrieve the activity indicator from QML so that we can start
    // and stop it from C++ code.
    myActivityIndicator = root->findChild<ActivityIndicator*>("indicator");
    myTextField = root->findChild<TextField*>("textFieldRetrived");
    myLabel = root->findChild<Label*>("lblRetrieve");
    textArea = root->findChild<TextArea*>("textArea");
    submitButton = root->findChild<Button*>("submitButtonQml");
//  navigationPane = root->findChild<NavigationPane*>("navigationPaneQml");
//  root = qml->createRootObject<NavigationPane>();

//  QmlDocument *qml1 = QmlDocument::create("asset:///splash.qml").parent(this);
////    mNewPage = new Page();
//   mNewPage = qml1->createRootObject<Page>();

    myNetworkAccessManager = new QNetworkAccessManager(this);
    connect(myNetworkAccessManager, SIGNAL(finished(QNetworkReply*)),
            this, SLOT(requestFinished(QNetworkReply*)));

    // Create a file in the file system that we can use to save the data model.
    myFile = new QFile("data/model.xml");

    app->setScene(root);
}

bool DemoProject2::isNetworkAvailable() {
    QNetworkConfigurationManager netMgr;
    QList<QNetworkConfiguration> mNetList = netMgr.allConfigurations(
            QNetworkConfiguration::Active);
    if (mNetList.count() > 0) {
        if (netMgr.isOnline()) {
            return true;
        } else {
            return false;
        }
    } else {
        return false;
    }
}

void DemoProject2::initiateRequest(QString text){
    text.trimmed();
    fprintf(stderr, "Debug::::::::::::::::::::::::::: %s\n","hhhh");
    isComplete = false;

    // Start the activity indicator.
        myActivityIndicator->start();
        myLabel->setVisible(true);
        myLabel->setText("Retrieving contact list ...");

        // Create and send the network request.
        QNetworkRequest request = QNetworkRequest();
            request.setUrl(QUrl("******************"));

        fprintf(stderr, "Debug::::::::::::::::::::::::::: %s\n","00");
        myNetworkAccessManager->get(request);
}

void DemoProject2::requestFinished(QNetworkReply* reply){
    fprintf(stderr, "Debug::::::::::::::::::::::::::: %s\n","NUM 0");

    myActivityIndicator->stop();
    myLabel->setVisible(false);

    // Check the network reply for errors.
    if (reply->error() == QNetworkReply::NoError){
        fprintf(stderr, "Debug::::::::::::::::::::::::::: %s\n","NUM 1");

        /****** Sax Parsing code Section..................******/
                QByteArray data = reply->readAll();
                xmlSaxParser(data);

        /****** dom parsing code section ........******/
//      QByteArray byteArray = reply->readAll();
//      xmlDomParser(byteArray);

        fprintf(stderr, "Debug::::::::::::::::::::::::::: %s\n","NUM 2");

        reply->deleteLater();

    }
}

bool DemoProject2:: getCompleteVariable(){

    return isComplete;
}


void DemoProject2 :: setLoginData(QString data){
    loginData = data;
}

QString DemoProject2 :: getLoginData(){

    while(!getCompleteVariable()){

        fprintf(stderr, "Debug::::::::::::::::::::::::::: %s\n","shivang");
    }

    return loginData;
}

void DemoProject2:: xmlSaxParser(QByteArray data){
    fprintf(stderr, "Debug::::::::::::::::::::::::::: %s\n","NUM 3");

    // The XML stream reader that is used to extract the articles from the RSS feed
    QXmlStreamReader m_xml;
    m_xml.addData(data);
    QString currentTag = "";
    QString linkString;
    QString titleString;

    while (!m_xml.atEnd())
    {
        m_xml.readNext();
        if (m_xml.isStartElement())
        {
            if (m_xml.name() == "contacts"){
                linkString = m_xml.attributes().value("title").toString();
                currentTag = m_xml.name().toString();
                myLabel->setVisible(true);
                myLabel->setText(linkString);
            }else if(m_xml.name() == "return"){
                currentTag = m_xml.name().toString();
                fprintf(stderr, "Debug::::::::::::::::::::::::::: %s\n","ns:return");
            }
        }
        else if (m_xml.isEndElement())
        {
            if (m_xml.name() == "return")
            {
                fprintf(stderr, "Debug::::::::::::::::::::::::::: %s\n","return");
                //               linkString = m_xml.attributes().value("rss:about").toString();
                                       titleString.clear();
                //                     linkString.clear();
            }

        } else if (m_xml.isCharacters() && !m_xml.isWhitespace())
        {
            if (currentTag == "return"){
                titleString += m_xml.text().toString();
                                   myLabel->setVisible(true);
                                                        myLabel->setText(titleString);
                                                        setLoginData(titleString);
//              textArea->setText(titleString);
//              currentTag = "";
            }
        }

    }

    if (m_xml.error() && m_xml.error() != QXmlStreamReader::PrematureEndOfDocumentError) {
        //             m_feeds.append(
        //                     QString::fromLatin1("XML ERROR: %1: %2").arg(m_xml.lineNumber()).arg(m_xml.errorString()));
    }

    fprintf(stderr, "Debug::::::::::::::::::::::::::: %s\n","NUM 4");

//  navigationPane->push(mNewPage);
    isComplete = true;
}



[B]DemoProject2.hpp[/B]

// Navigation pane project template
#ifndef DemoProject2_HPP_
#define DemoProject2_HPP_

#include <QObject>

#include <QFile>

#include <QString>
#include <bb/cascades/ActivityIndicator>
#include <bb/cascades/TextField>
#include <bb/AbstractBpsEventHandler>

#include <bb/cascades/Application>
#include <bb/cascades/Label>
#include <bb/cascades/TextArea>
#include <bb/cascades/Button>
#include <bb/cascades/NavigationPane>
#include <bb/cascades/Page>
using namespace bb::cascades;

namespace bb { namespace cascades { class Application; }}

/*!
 * @brief Application pane object
 *
 *Use this object to create and init app UI, to create context objects, to register the new meta types etc.
 */
class DemoProject2 : public QObject
{
    Q_OBJECT
public:
    DemoProject2(bb::cascades::Application *app);
    virtual ~DemoProject2() {}

// void parseXml (QByteArray data);

    Q_INVOKABLE void initiateRequest(QString text);
    Q_INVOKABLE bool isNetworkAvailable();

    Q_INVOKABLE void xmlSaxParser(QByteArray data);

    Q_INVOKABLE void xmlDomParser(QByteArray data);
    Q_INVOKABLE QString getLoginData();
    Q_INVOKABLE void setLoginData(QString data);
    Q_INVOKABLE bool getCompleteVariable();

//    NavigationPane *root;
//    signals:
//        void networkStatusUpdated(bool status, QString type);

    private slots:
        void requestFinished(QNetworkReply* reply);
//        void networkStatusUpdateHandler(bool status, QString type);

private:
    bb::cascades::TextField *myTextField;
    bb::cascades::ActivityIndicator *myActivityIndicator;
    bb::cascades::Label *myLabel;
    bb::cascades::TextArea *textArea;
    bb::cascades::Button *submitButton;
//    bb::cascades::NavigationPane* navigationPane;
//    bb::cascades:: Page* mNewPage;

    QNetworkAccessManager *myNetworkAccessManager;
       QFile *myFile;
       QString loginData;
       QByteArray data;
       bool isComplete;
//       Page* mNewPage;


//       StatusEvent *statusEvent;
};

#endif /* DemoProject2_HPP_ */
Shivang
  • 935
  • 8
  • 18

1 Answers1

2

use event loop....

QNetworkAccessManager* netManager = new QNetworkAccessManager();
    QUrl myurl("http://******");
    QNetworkRequest req(myurl);

QNetworkReply* ipReply = netManager->get(req);

QEventLoop eventLoop;
QObject::connect(ipReply, SIGNAL(finished()), &eventLoop, SLOT(quit()));
eventLoop.exec();
std::cout << "finished" << std::endl; //request finished here
requestFinished(ipReply);
Shivang
  • 935
  • 8
  • 18
  • he already answered how to use the event loop. it'll basically block execution (wait) until the quit slot is called when the finished signal is triggered after the reply is finished. in short. it'll block at "exec()" until its done with the reply. you could also avoid using eventloop if: you implement a slot for the finished reply. or maybe use the blocking connection type (which im not sure its possible for network events) – Nande Jun 25 '14 at 23:41