I'm wondering if anyone has any tips or tricks around importing and using external javascript libraries within AppStudio?
There are a couple of libraries that I use a lot in Node that I would like to use occasionally in AppStudio that I can't figure out how to import and use. One is moment.js and the other is Turfjs, and there are others too. There was an older version of moment.js that worked but with AppStudio 3.x it stopped working so I had to switch to using Luxon.
If anyone has any tips then please let me know, and/or if you can specifically find a way to get either of those libraries working!
cheers,
-Paul
Hi Paul,
I did some troubleshooting but found that the "moment.js" works by default, e.g.
Here's an example usage:
import QtQuick 2.7
import ArcGIS.AppFramework 1.0
import "moment.js" as Moment
App {
id: app
width: 400 * AppFramework.displayScaleFactor
height: 640 * AppFramework.displayScaleFactor
Column {
anchors.fill: parent
anchors.margins: 10
spacing: 10
Text {
text: JSON.stringify( moment() ) // "2019-09-06T21:46:33.916Z"
}
Text {
text: moment().format('MMMM Do YYYY, h:mm:ss a') // September 7th 2019, 7:47:08 am
}
Text {
text: moment().format("dddd") // Saturday
}
Text {
text: moment().format('YYYY [escaped] YYYY') // 2019 escaped 2019
}
Text {
text: moment().format() // 2019-09-07T07:48:57+10:00
}
}
}
Hi Stephen
Not sure what's happened with the replies in Geonet, I got an email alert with one set of instructions but then when I went to reply online I see a different reply above?
You mention above that moment.js works fine for you, but that's not my experience, it fails to load each time.
However, if I follow your comments from the email alert that I got, it does work! I have pasted that below here in case anyone else experiencing same issues as me....
Hi Paul,
I did a small edit to the "moment.js" to make it work.
//! moment.jsvar moment;;(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : moment = global.moment = factory()}(this, (function () { 'use strict';//...
Hi Paul,
I had numerous attempts at this over the weekend.
The first version I did was the workaround which you got a copy from the email.
However, I found the workaround ugly.
When I retested the "import" as is, I found it to just work with my version of AppStudio.
I will do some further troubleshooting, but, can you tell me which version of Qt you are using?
Stephen
Am using AppStudio v4.0.93, which uses Qt v5.12.3.
Thanks Paul,
I'm using a similar version.
In one of the troubleshooting sessions, I modified the header of "moment.js" to the following:
//! moment.js
;(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
global.moment = factory()
console.log("typeof(global): ", typeof(global));
global[ "one" ] = 1;
global[ "two" ] = 2;
global[ "three" ] = 3;
global[ "key" + Math.random() ] = 1;
console.log("global keys: ", JSON.stringify( Object.keys( global ) ) );
}(this, (function () { 'use strict';
Then in my app, I imported "moment.js" twice:
import "moment.js" as Moment1
import "moment.js" as Moment2
On the first import, this yielded the following output:
qml: typeof(global): object
qml: global keys: ["moment","one","two","three","key0.3286030239782699"]
On the second import, this yielded the following:
qml: typeof(global): object
qml: global keys: ["moment","one","two","three","key0.3286030239782699","key0.7088453144951244"]
i.e. what appears to be happening, is the value of "this" which later becomes "global" refers to Javascript object in the global namespace. What the moment.js library is trying to do is install a moment() as a function in the global namespace. For good measure, I wanted to see if I can put some random keys in the global namespace as well, and, yes, that appears to have worked too.
This means when you use these objects in your app, you don't need to use the specifier, i.e. I didn't use either Moment1 nor Moment2. I just referred to the moment() function directly.
Similarly, for the other items I added in the global namespace, I could access them too, e.g.
Text {
text: three // 3
}
If you still cannot get it to work, then, yes, feel free to refer to my workaround, i.e.
//! moment.js
var moment
;(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
global.moment = factory()
moment = global.moment
}(this, (function () { 'use strict';
Then, in your app, use the workaround as follows:
import QtQuick 2.7
import QtQuick.Controls 2.1
import ArcGIS.AppFramework 1.0
import "moment.js" as Moment
App {
id: app
width: 400
height: 640
property var moment: Moment.moment
Text {
text: moment().format("dddd")
}
}
Stephen