Hexagon Geospatial
MENU

Smart M.App

Looking for answers in regards to M.Apps, M.App Exchange or M.App Studio? Smart M.App Tech Discussion board is where you can search, ask your questions and assist others by sharing your knowledge. Join the conversation, connect, contribute and share.
Showing results for 
Search instead for 
Do you mean 
Reply
Highlighted
Technical Evangelist
Posts: 1,034
Registered: ‎09-11-2015

Creating data download button

[ Edited ]

I've been developing a simple download button functionallity to kind of mimic the functions on M.App Chest. I think this will be handy to other developers so I'm going to share my results.

For tests I used a single Custom Panel containing a text box and single button.

<div style="margin: 50px">
    Asset ID:
    <input type="text" id="inputID" name="id" value="insert-your-file-id-here">
    <br />
    <button type="button" id="btnDownload1">Issue the download</button>
</div>

1.png

 

When user clicks for the first time, the button turns into a waiting state:

1.png

(progress log can be seen in the developer console)

 

Once the download is prepared, the button changes again and points directly to the download URL on the server:

3.png

 

The asset ID is an unique ID of item stored on the cloud and can be checked e.g. by M.App Chest. You should also get those IDs as results from geoprocessing - i.e. Spatial Recipe will produce one or more output files and in the callback it returns you an array with those file IDs. Please see Code Examples - 06. Catalog Operations > Publish catalog item and send to map for more info.

 

Sample ID from M.App Chest:

3.png

 

And now the full JS code that I used. I know it's not perfect (I'm not JavaScript expert) but it works. Wisers will certainly fix it Smiley Wink

 

function changeMe(url) {
    $("#btnDownload1").prop('disabled', false);
    $("#btnDownload1").html('Download ready!');
    $("#btnDownload1").unbind()
    $("#btnDownload1").click(function() { window.location = url; })
}

function PrepareDownload(itemId, callback) {
   if (!itemId) return;

	var isCallingStatus = false;
	var layerToDownload = [];
	layerToDownload.push(itemId);

	// Issue download request, files will be zipped
	gsp.m_app.utils.connection({
		path : 'api/v1/downloads',
		method : 'POST',
		entity : layerToDownload
	}).then(function (success) {

		var downloadId = success.entity.id;
		var timer = setInterval(function () {
				// ensures we don't overload the server if we don't get a timely response
				if (isCallingStatus)
					return;
				isCallingStatus = true;
				console.log("Waiting...");

				// Ask for status
				gsp.m_app.utils.connection({
					path : 'api/v1/downloads/' + downloadId,
					method : 'GET'
				})
				.then(function (message) {
					if (message.entity.state == "CANCELLED") {
						clearInterval(timer);
						alert("Download: " + message.entity.state);
					} else if (message.entity.state == "FAILED") {
						clearInterval(timer);
						alert("Download: " + message.entity.state);
					} else if (message.entity.state == "COMPLETE") {
						console.log("SUCCESS");
						var link = message.entity.downloadURI.replace("http://datamanagement.hexagongeospatial.vpc/api/v1/", "https://mapp.hexagongeospatial.com/api/v1/");

						// get API key and build download link
						var APIKey = null;
						gsp.m_app.utils.connection('uaa/apikey').then(function (res) {
							if (!res) {
								console.log("Could not retrieve API key!");
								return;
							}
							APIKey = res.entity[0].APIKey;
							link += "?apiKey=" + APIKey;
							console.log(link);
							callback(link);
						}, function (error) {
							console.log("GET API LINK error");
							console.log(error);
						});
						clearInterval(timer);
					}
					isCallingStatus = false;
				}, function (error) {
					console.log("GET STATUS error");
					console.log(error);
				});
			},
				1500);
	}, function (error) {
		console.log("POST Download error");
		console.log(error);
	});
}

$("#btnDownload1").click(function() {
    $("#btnDownload1").html('Preparing...');
    $("#btnDownload1").prop('disabled', true);
    PrepareDownload($("#inputID").val(), changeMe);
});

Hope this helps.

Jan Neumann
Post Sales Engineer Web Applications
Hexagon Geospatial

Do you need immediate support?
Please submit a Ticket through our
Development Ticket Portal.