Select to view content in your preferred language

JASPI 4.24+ Get JSON for current webmap state

301
3
02-04-2025 09:27 AM
Arne_Gelfert
Frequent Contributor

I'm currently in the process of converting some JSAPI 3.x code to 4.x.

It used to be you could do this in 3.x 

 

//Use 
esri/tasks/PrintParameters,
esri/tasks/PrintTask


//To get this
var params = new PrintParameters();
var webMapAsJSON = printTask._getPrintDefinition(<currentMap>, params);

 

webMapAsJSON could then be sent to a custom geoprocessing service using

 

var gp = new Geoprocessor("your service's url")

 

and manipulated to your heart's delight in Python on the back end.

Looks like "PrintTask" was deprecated back in 4.24... is there any way to still grab that JSON? I do not just want to send current state of web map to a layout using the new "print" module. I have all kinds of existing logic in arcpy that I  want to apply before creating a PDF.  

3 Replies
JoelBennett
MVP Regular Contributor

Yes, this can be achieved in 4.x, primarily through the use of a RequestInterceptor.  Basically, you'll use the interceptor to capture a print request, get the web map JSON from the request, and then cancel the request before it gets sent.  This has several pieces.

First, you should define a URL to a print service.  Note that in our workflow, a request will never actually get sent to it, but it's best to specify a valid one:

var printServiceURL = "https://utility.arcgisonline.com/arcgis/rest/services/Utilities/PrintingTools/GPServer/Export%20Web%20Map%20Task";

 

Next, somewhere near where your application starts (e.g. where the View is created), you would set up your interceptor:

require(["esri/config"], function(esriConfig) {
	esriConfig.request.interceptors.unshift({
		urls: printServiceURL + "/execute",
		before: function(params) {
			var error = new Error("cancel");
			error._webMapAsJSON = JSON.parse(params.requestOptions.query.Web_Map_as_JSON);
			return error;
		}
	});
});

 

Elsewhere, you can create a function that accepts a reference to your view, and returns a Promise with the web map JSON:

function getWebMapAsJSON(view) {
	return new Promise(function(resolve, reject) {
		require(["esri/rest/print", "esri/rest/support/PrintParameters", "esri/rest/support/PrintTemplate"], function(print, PrintParameters, PrintTemplate) {
			var printTemplate = new PrintTemplate({
				//whatever parameters desired
			});

			var printParameters = new PrintParameters({
				 //add other parameters as necessary
				template: printTemplate,
				view: view
			});

			print.execute(printServiceURL, printParameters).then(function(){}, function(e) {
				resolve(e._webMapAsJSON);
			});
		});
	});
}

 

And then elsewhere you can call this function to get the JSON and do whatever you want with it:

getWebMapAsJSON(view).then(function(webMapAsJSON) {
  console.info(webMapAsJSON);
});

 

0 Kudos
Arne_Gelfert
Frequent Contributor

Hey @JoelBennett - Thanks. Really appreciate you chiming on . I will take a look at this. But I have to wonder why something so simple had to become so complicated. Haha. I looked at the V3 code in PrintTask and it looks like a bunch of  toJSON() functions were used to get the mapOptions and a _createOperationsLayers call to get the layers. All that was returned a JSON dictionary. --- I'll let you know if I can get your examples there to work. Thanks again.

0 Kudos
JoelBennett
MVP Regular Contributor

@Arne_Gelfert wrote:

I have to wonder why something so simple had to become so complicated.


The logic that generates the web map JSON can be seen in the esri/rest/print module, but due to the way it's encapsulated, it's impossible to get to in the same manner as 3.x.

0 Kudos