ArcGIS API for JavaScript – Parsing Geoprocessing Service Messages with ArcGIS API for JavaScript

arcgis-javascript-apiarcgis-servergeoprocessing-servicepythonweb service

I am working on a JavaScript (JS) app where the user draws a polygon and then a python-based Geoprocessing (GP) Service task queries the parcels and generates mailing labels. The GP task works great, but once the PDF is created I need to open the hyperlink in a new tab.

What I really need to get at is the return of my Python function:

# as a trivial example:
def myFunc(*args):
    # do something
    return output_url  # this is what I want to access!

So in my gp task, the function is returning the hyperlink url needed to download the report. I do not think there is an out of the box way to get the gp result. So the other thing I am thinking is to parse the messages returned from the GP Service. I have looked through the help docs and do not see a sample how to get at the messages. I'm new the JS development, so it's probably there and I'm just missing it.

My call to the gp task:

var gp = new Geoprocessor("http://myServer.com/arcgis/rest/services/GP_TASKS/MailingLabels/GPServer/MailingLabels");

function OpenInNewTab(url) {
    var win = window.open(url, '_blank');
    win.focus();
  };  

var gpParams = {
    "Boundary": fs,
    "Site": "Paynesville",
    "Mailing_Type": "taxpayer"
  };
gp.execute(gpParams);
var URL = ""; #need to get this from result OR parse messages

gp.on("execute-complete", OpenInNewTab(URL));

And here is an example of the JSON from the GP service messages:

{
 "results": [

 ],
 "messages": [
  {
   "type": "esriJobMessageTypeInformative",
   "description": "Executing (MailingLabels): MailingLabels \"Feature Set\" Paynesville taxpayer"
  },
  {
   "type": "esriJobMessageTypeInformative",
   "description": "Start Time: Wed Mar 25 11:29:45 2015"
  },
  {
   "type": "esriJobMessageTypeInformative",
   "description": "Executing (MailingLabels): MailingLabels \"Feature Set\" Paynesville taxpayer"
  },
  {
   "type": "esriJobMessageTypeInformative",
   "description": "Start Time: Wed Mar 25 11:29:45 2015"
  },
  {
   "type": "esriJobMessageTypeInformative",
   "description": "Running script MailingLabels..."
  },
  {
   "type": "esriJobMessageTypeInformative",
   "description": "Creating labels in Avery 5160 format"
  },
  {
   "type": "esriJobMessageTypeInformative",
   "description": "\nCreated \\\\arcserver2\\wwwroot\\TempFiles\\MailingLabels_taxpayer20150325112946.pdf\n"
  },
  {
   "type": "esriJobMessageTypeInformative",
   "description": "http://myServer.com/TempFiles/MailingLabels_taxpayer20150325112946.pdf"
  },
  {
   "type": "esriJobMessageTypeInformative",
   "description": "Completed script MailingLabels..."
  },
  {
   "type": "esriJobMessageTypeInformative",
   "description": "Succeeded at Wed Mar 25 11:29:47 2015 (Elapsed Time: 1.85 seconds)"
  },
  {
   "type": "esriJobMessageTypeInformative",
   "description": "Succeeded at Wed Mar 25 11:29:47 2015 (Elapsed Time: 1.85 seconds)"
  }
 ]
}

There is nothing in the "results", so since I am actually printing out the URL needed in the messages, I'm thinking I can parse these somehow. So my questions are:

  1. Is there a way I can get the return URL from my Python function back as a result from the GP Service?

  2. If the answer to number 1 is no, how do I get at the result messages and step through them? This is a Synchronous task so I am using the execute() method.

Best Answer

I'd really recommend against parsing the output messages. For one, it'll be tedious. And more importantly, 2, you have INFO level messages on. INFO level displays path information to resources on the Server machine. Many people would consider this a security risk (leaving this level of information available to anyone consuming a service)

So here's some JavaScript code (async consumption) that returns the URL to a file produced by a GP Service. It shouldn't be much to hack it to support execute (sync).

[javascript code]

gp.submitJob(params, gpJobComplete, gpJobStatus, function(error){
          alert(error);     

function gpJobComplete(jobInfo) {  

      if(jobInfo.jobStatus == "esriJobFailed") {                            
        dojo.byId('downURL').innerHTML = "Failed to generate text file";        
       }    
       else if (jobInfo.jobStatus == "esriJobSucceeded") {                  
            gp.getResultData(jobInfo.jobId,"Output_Text_File", downloadFile);           
      }
    }    

    function downloadFile(outputFile) {  

       var theurl = outputFile.value.url;
//or you could insert a TARGET= ____ for an appropriate action in the <a>
       dojo.byId('downURL').innerHTML = "<a href='"+ theurl + "'>Download File (right-click, save-as)</a>";  
    }   

//Heres a function that gets and stuffs all the messages into a global var and updates a dojo text box
    function gpJobStatus(jobInfo) {  

       for (m, ml=jobInfo.messages.length; m<ml; m++) {
          xMsgs += jobInfo.messages[m]["description"] + "\n";               
       }        
        dojo.byId('messages').value = xMsgs;

    }   

[/javascript code]

[htmlcode]

//this produces a new, in-line clickable link from the downloadFile function
  <div id="downloadURLDiv">    
    <span id="downURL"></span>
  </div> 

[/htmlcode]

Related Question