JavaScript Promises with ArcGIS Runtime SDK for Qt

07-05-2016 02:27 PM
Labels (1)
Esri Frequent Contributor
1 0 1,917

We have discussed the relationship of QML with JavaScript in previous blogs, and are seeing more and more Esri web developers build native apps with the QML and Qt framework. Many of these developers have given us feedback about how much they enjoy Qt and QML, and have stated that the transition from building HTML5/JS based web apps to QML/JS based native apps was very smooth. One of the common question we get asked by JS devs interested in QML is if QML supports JavaScript promises. While this pattern is not directly built into QML, it is easily doable with a QML library called QuickPromise, which is available project on GitHub.

For those of you not familiar with JavaScript Promises, the patterns and specification are explained in great detail here. The important thing to know is that it is a very productive way to work with asynchronous methods, and can be especially helpful when you are running several async methods concurrently, and you want some action to occur once all of those async methods are complete. A great example in the case of ArcGIS Runtime is when you are wanting to take your data offline. Imagine that you have an app that does editing in an online and offline mode. Initially, your data is online, and your user can edit directly against the service. You also have a button to take the data offline, in which case all of your feature services will generate geodatabases, and your tiled service will export all of the tiles into a local tile package. When your user presses the button, you want to display a screen that indicates the download is in progress, and you don't want that screen to go away until all of the asynchronous operations are complete. Also, once everything is complete, you want to remove the online layers from your map, and add in the offline layers. How would you accomplish this? There may be several ways to do this, but one great way to do this is with promises in QML (QuickPromise).

Screen Shot 2016-07-05 at 1.52.50 PM.png

I set out to try the above scenario to see if I could come up with a clean way of doing this with the QuickPromise library. Here were the steps I took:

  • I first installed the Quartz beta release of the ArcGIS Runtime SDK for Qt, and I cloned the Qt Sample repo on GitHub. I then combined the GenerateGeodatabase and ExportTiles samples into one project, so that I had an app that would both take a feature service and a tiled map service offline.
  • Next I cloned the QuickPromise repo, and followed the installation instructions in the project's readme. It was really as simple as cloning the project, including the pri file in my project, and adding an import path to the app engine, as explained in the read me.
  • Finally, I imported the QuickPromise plugin in my QML file, and I created a Promise. I set the Promise's resolveWhen property to list a list of signals (each signal emits when one of the offline tasks completes). Finally, I created a signal handler for the fulfilled signal- this signal will emit once all of the promises are resolved. In this case, I want to update the download screen once all of the promises are resolved, and I also want to switch out my online layers to my offline layers.

Screen Shot 2016-07-05 at 1.48.35 PM.png

This worked wonderfully, and was very simple to setup and use. I found that this particular usage of QuickPromise worked wonderfully for the declarative type QML workflow. Beyond this, there are several other ways you can use QuickPromise, both declaratively, and in imperative JavaScript code. Many of the alternative functions fit more into the traditional pattern of how a JavaScript Promise is used in a web application (e.g. a then() function). The alternative methods of creating a promise in QML are documented here.

If you are interested in giving this a try, I attached my sample project to this blog post. In order to build/run this sample on your machine, you will need to install the Quartz beta 1 release of ArcGIS Runtime SDK for Qt, install QuickPromise, and update the path to the pri file in the project's pro file.

About the Author
I'm a Geographer working in Product Development at Esri, focusing my time on the ArcGIS Runtime SDKs. I'm an Esri Certified ArcGIS Desktop Professional (10 years experience working with ArcGIS) with a wide range of technical skills including native application development, spatial databases, desktop/web GIS, and scripting. My Master's degree is in GIS with a focus in Natural Resource Management. Currently, I'm most interested in building cross-platform and lightweight apps using our ArcGIS Runtime SDK for Qt.