Is there any way to use synchronous function call through Qt WebChannel? - qt

Unlike Qt WebKit Bridge, I couldn't find to use synchronous function call on JS side using Qt WebChannel.
Is there any way to do so?

I think there's no way to do it. It is said in the documentation : QWebChannel
Note that all communication between the HTML client and the QML/C++
server is asynchronous.
Moreover, it is precisely said in this blog : Bridge the gap between C++/QML and the web
But, contrary to the WebKit Bridge, the API provided by the WebChannel
is completely asynchronous.
Hope that helps.

Related

React Native best practices for API handling

I've been working on the React Native platform this last couple of months and I need to implement a solid way to handle my API calls. At the moment I'm using redux to manage satate changes. Obviously the requestes must have a couple of retries if there is no network available, refresh oAuth tokens, etc.
Three solutions have ocurred to me:
Implement a "manager" class and handle all the logic in there. I like this one but I don't know if is possible to connect a non-component to redux since they dont have state.
Implement a couple of redux actions(request, onResponse, onError...) which should do the trick.
Create separated redux actions with their own fetchs to every call instead of having a centralized component.
What solution should I implement?
Another problem I've faced is that if a Network Error happens the promise is resolved even if I call the request again and I'm no longer able to make the behavior programmed in the caller method. Any workarounds?
Thank you for your time.
Redux has two powerful libraries that are designed to work with async API calls. These allow you to handle retries, errors, and slow API calls in the background of your app, simply by listening for a specific action.
Redux-thunk or Redux-saga are what you are probably going to want to use, so that you do not have to do all of the work of managing how components deal with API calls. Strongly recommend you check these out - there are quite a few tutorials out there that describe how to use these modules. Doing this by hand is not a good best practice IMO.
For api handling. you can have one single file which will have all function (export) and other settings needed so that you just have to import required methods.
You can use starter kit for react-native for basic structure for example: https://github.com/futurice/pepperoni-app-kit
it provides most of the things that we need for fresh project setup.
Follow the pattern mentioned in the below tutorial(youtube link below)
https://www.youtube.com/watch?v=9mlwjZL3Fmw
Everyone uses this pattern for API calls when following redux in react-native.
The tutorial is really good,its a great video.

How can I call in a sync manner C++ methods from JS (QtWebEngine)

Is there a way I can call my C++ methods from JS in a sync (instead of async) manner? (I'm using QtWebChannel).
If there is not, can I at least use async/await without transpiling?
I don't think is possible to use sync manners. The doc said "Note that all communication between the HTML client and the QML/C++ server is asynchronous".
-> https://doc.qt.io/qt-5.9/qtwebchannel-javascript.html

QHttpResponseHeader is obsolete and removed from Qt5

In my project, I used QHttpResponseHeader in Qt4.8.6, but it became obsolete and it is not
available anymore in Qt5. What is its equivalent class in Qt5?
There is an equivalent already available in Qt4.8 : look at the QNetworkReply class, particularly the header() and rawHeader() functions. It should be what you are looking for.
A bit of explanation : QNetworkAccessManager is the class which allows you to send and receive requests. It is much more flexible and not limited to a single protocol, in contrast to QHttp/QFtp. Before, you had to decide on the application level which protocol to use, and now you only pass an URL to the QNetworkAccessManager, it will manage the rest.

Some queries on QSettings, qmlRegisterType() and setContextProperty

I will try explaining my confusion through the application I am currently developing.
My application (based on Qt5.1 + Qt Quick Controls) interacts with Facebook API to manage a Facebook Page. I am trying to keep the QML code (for UI) as separate as possible from the C++ core.
Now, an OAuth2 implementation is required to be able to interact with Facebook API. For that, I have a C++ OAuth2 class, the constructor of which has the following signature:
OAuth2::OAuth2(QString appId, QString redirectUrl, QStringList permissions);
Now, as the OAuth process requires a browser, I have also implemented an OAuthBrowser.qml, which uses OAuth2 to complete an authorization.
I have the following options to expose OAuth2 class to OAuth2Browser:
Instantiate OAuth2 and use setContextProperty() to expose the instance to OAuth2Browser. However, this means my C++ code has to deal with the UI code. The more baffling issue is that OAuth2Browser is a secondary window. When a user clicks on a "Authorize" window on the MainWindow, then an
AppController C++ object (connected to MainWindow) will launch the OAuth2Browser window. Thus, the instantiation code of OAuth2Browser would go deep down inside a AppController method. It would have been good if only main.cpp had to deal with the window creation.
Use qmlRegisterType(). In this case, I can't pass parameters to the constructor. So, I will have to implement an init() method that would initialize an OAuth2 object. Then, I would call this init() method in OAuth2Browser's Component.onCompleted() method.However, in this approach, I will have to expose QSettings to the UI code - QML window, so that the required parameters to init() method can be retrieved. I have huge skepticism on whether directly exposing application settings to QML UI is a good idea.
Implicitly use QSettings within the OAuth2 constructor. This way, I won't have to pass any parameters, and I would be able to use qmlRegisterType(). However, this means I am doing some magic stuff "behind the curtains". Instead of explicitly passing QSettings instance, I am using it wherever the hell I want to, thus hiding the initialization detail from public API.
An alternative based on the 3rd option was advised on IRC - use an initFromSettings() type of method to initialize an instance if no parameter is passed to the constructor. That way, the initialization is not hidden, and initFromSettings() can confidently use QSettings within itself. Now, I can happily use qmlRegisterType() to instantiate OAuth2 in QML.
So, what is the better approach?
Also,
Is exposing QSettings directly to QML UI a good idea?
I personally prefer qmlRegisterType() to setContextProperty() - that way, the lifetime of a registered class's instance is maintained solely by QML. However, the former is less likely to be used due to the lack of support of parameterized constructors, unless some form of init() is used
explicitly for initialization. Is that a good design?
I apologise in advance for an excruciatingly long post. But I thought it best to ask here.
It's difficult to fully follow your post since it's so long and information dense. Here are my suggestions for what they might be worth.
You want to know what is a good design but you don't specify your goals. You can't really rate something for how well it achieves goals unless you can enumerate the goals.
You're dealing with facebook's api. My crystal ball says change is something you will need to deal with. Therefore putting all the tools into qml may make you better able to respond to change. You can respond to change by rewriting javascript in a qml file instead of a recompile (hopefully). Use properties and the signal/slot design and it should be flexible enough to get the job done. Performance doesn't seem to be an issue.
I would create a settings object that exposes the stuff you want to store. Perhaps using the model/view architecture Qt provides already. The underlying storage, xml file, database, QSettings registry isn't important. You can offer a grid/list to allow users to update their settings if necessary.
Put together oauth and browser tools as objects that will let you script the behavior of the app in qml.
These tools to expose c++ objects might be something excellent to share with the community as well.
Good luck!

Disappointed with BlazeDS... are there ways around these disadvantages?

I used to use soap webservices for transferring chart data to my flex app, but recently switched over to using BlazeDS because of performance, convenient typing, etc.
I'm considering switching over to using JSON (as I do in other parts of the app) for these reasons:
Proliferation of DTOs for communicating with flex.* (With JSON, I just use JsonConfig to exclude properties as desired.)
Difficult to debug (whereas JSON is good ol' plaintext).
Problems with load balancing without sticky sessions.
Anyone else run into these problems with BlazeDS? Is BlazeDS worth the hassle?
* I could use the Externalizable interface instead of distinct DTOs, but it's also a pain.
I wouldn't give up on using remoting. Performance of remoting will be much better than JSON. Remember ActionScript doesn't have a method to decode JSON, so you'd need to use an AS library which will be slower than anything built into the player. You'd be better of using XML than JSON.
You should be able to exclude specific properties as desired by marking them as transient. ActionScript has [Transient] metadata and the idea came from Java. The C# library we use for remoting has Transient support. I'm sure BlazeDS does too.
Debugging is easy with the right tools. You should get Charles. It provides very nice views of AMF request and response messages (assuming you're using HTTP and not RTMP, I don't know about RTMP debugging).
http://www.charlesproxy.com/
You also seem to be choosing between BlazeDS and anything-not-remoting. You have more options. BlazeDS is just one remoting implementation that Adobe made available. They also have a commercial one. There are also many open-source remoting projects available. We use a wonderful one for C# called Fluorine. Open-source Java options are Red5 and OpenAMF, but I think there are others as well.
http://red5.org/
http://openamf.com/
There's also a distinction between RTMP and HTTP remoting. You can get data into Flex through either of these protocols and each will have it's advantages/disadvantages. I personally prefer HTTP remoting unless you absolutely need the functionality RTMP provides (push, streaming). HTTP will be easier to debug and should not have problems with a load balancer--it's just HTTP calls where the content happens to be binary.

Resources