How to set headers for esriRequest using .setRequestPreCallback()

1807
2
Jump to solution
07-02-2019 12:05 PM
JustinBridwell2
Occasional Contributor II

I want to add an api-key to the header of my esriRequest. I first created a callback function. 

function myCallbackFunction(ioArgs){
            ioArgs.headers = ioArgs.headers || {}; // make sure headers are not null
            ioArgs.headers["api-key"] = "<123mykey>" // add custom headers
            return ioArgs;
    }

My esriRequest is triggered by a button click after the lat, long have been captured. I placed by .setRequestPreCallback() that calls my myCallbackFunction right before the request is made, inside the click event.

wind_url = "https://api-hazards.atcouncil.org/public/v1/";
document.getElementById("btnGetWindspeed").onclick = function () {
 if (additionalInfo["pointGeomOfInterest"] !== undefined) {
    var lat = additionalInfo["pointGeomOfInterest"].y;
    var long = additionalInfo["pointGeomOfInterest"].x;
  }

  if (additionalInfo["pointGeomOfInterest"] === undefined) {
        alert("Choose a location!");
  } else {
    var base_url = wind_url + "wind.json";
    var lat = additionalInfo["pointGeomOfInterest"].y;
    var long = additionalInfo["pointGeomOfInterest"].x;
    esriRequest.setRequestPreCallback(myCallbackFunction);
    var windRequest = esriRequest({
    url: base_url,
    content: { "lat": lat,
    "lng": long
    },
    dataType:"jsonp",
    handleAs: "json",
    callbackParamName: "callback"
    });
    windRequest.then(
    function(response) {
    wind_data = response.response.data;
    console.log("Success: ", wind_data);
    addWindspeedTable(wind_data);
  }, function(error) {
    console.log("Error: ", error.message);
  });
};

However, the callback function fails and I get the following error that the api has not been authorized: `Failed to load resource: the server responded with a status of 401 (Unauthorized)`. Am I adding the headers incorrectly, utilizing the .setRequestPreCallback() wrong, or is something else going on? Note: I have validated the api key and url in Postman and gotten a correct response.

                                                                                                                               

0 Kudos
1 Solution

Accepted Solutions
JustinBridwell2
Occasional Contributor II

This issue was resolved by doing a few simple things that were not obvious at a glance. First, there is a CORS issue using this method. Unfortunately, the errors I was receiving in the browser console did not clue me into this and I discovered it by accident (I am using another esriRequest in the script that required this fix). I simply added the following code at the top after listing my required functions:

esriConfig.defaults.io.corsEnabledServers.push("api-hazards.atcouncil.org"); // supports CORS

I also refactored my callBack function to include the .indexOf method as in the documentation:

function myCallbackFunction(ioArgs){
            if (ioArgs.url.indexOf("https://api-hazards.atcouncil.org") > -1) {
                ioArgs.headers = ioArgs.headers || {}; // make sure headers are not null
                ioArgs.headers["Api-Key"] = "<123mykey>" // add custom headers
                }
                return ioArgs;
        }

Finally, I had to add the .setRequestPreCallback call before the button click, not inside it (even if it is before the actual esriRequest. callbackParamName: "callback" also had to be removed. These changes were slight, but absolutely crucial to making this work. I am a little frustrated that the documentation does not contain clearer instructions on applying headers and keys to an esriRequest. This is a common task for anyone using a 3rd party API and there are no practical examples (or mentions of potentials issues like the CORS problem) to illustrate the correct application. 

esriRequest.setRequestPreCallback(myCallbackFunction);
        
//Get Wind Speed Data button click function
        document.getElementById("btnGetWindspeed").onclick = function () {
            if (additionalInfo["pointGeomOfInterest"] !== undefined) {
                var lat = additionalInfo["pointGeomOfInterest"].y;
                var long = additionalInfo["pointGeomOfInterest"].x;
            }

            if (additionalInfo["pointGeomOfInterest"] === undefined) {
                        alert("Choose a location!");
            } else {
                var base_url = wind_url + "wind.json";
                var lat = additionalInfo["pointGeomOfInterest"].y;
                var long = additionalInfo["pointGeomOfInterest"].x;
                var windRequest = esriRequest({
                    url: base_url,
                    content: {
                        "lat": lat,
                        "lng": long
                    },
                    dataType:"jsonp",
                    handleAs: "json"
                });

View solution in original post

2 Replies
JustinBridwell2
Occasional Contributor II

This issue was resolved by doing a few simple things that were not obvious at a glance. First, there is a CORS issue using this method. Unfortunately, the errors I was receiving in the browser console did not clue me into this and I discovered it by accident (I am using another esriRequest in the script that required this fix). I simply added the following code at the top after listing my required functions:

esriConfig.defaults.io.corsEnabledServers.push("api-hazards.atcouncil.org"); // supports CORS

I also refactored my callBack function to include the .indexOf method as in the documentation:

function myCallbackFunction(ioArgs){
            if (ioArgs.url.indexOf("https://api-hazards.atcouncil.org") > -1) {
                ioArgs.headers = ioArgs.headers || {}; // make sure headers are not null
                ioArgs.headers["Api-Key"] = "<123mykey>" // add custom headers
                }
                return ioArgs;
        }

Finally, I had to add the .setRequestPreCallback call before the button click, not inside it (even if it is before the actual esriRequest. callbackParamName: "callback" also had to be removed. These changes were slight, but absolutely crucial to making this work. I am a little frustrated that the documentation does not contain clearer instructions on applying headers and keys to an esriRequest. This is a common task for anyone using a 3rd party API and there are no practical examples (or mentions of potentials issues like the CORS problem) to illustrate the correct application. 

esriRequest.setRequestPreCallback(myCallbackFunction);
        
//Get Wind Speed Data button click function
        document.getElementById("btnGetWindspeed").onclick = function () {
            if (additionalInfo["pointGeomOfInterest"] !== undefined) {
                var lat = additionalInfo["pointGeomOfInterest"].y;
                var long = additionalInfo["pointGeomOfInterest"].x;
            }

            if (additionalInfo["pointGeomOfInterest"] === undefined) {
                        alert("Choose a location!");
            } else {
                var base_url = wind_url + "wind.json";
                var lat = additionalInfo["pointGeomOfInterest"].y;
                var long = additionalInfo["pointGeomOfInterest"].x;
                var windRequest = esriRequest({
                    url: base_url,
                    content: {
                        "lat": lat,
                        "lng": long
                    },
                    dataType:"jsonp",
                    handleAs: "json"
                });
fanxiaoxiao
New Contributor

hello,i want to say that after esriRequest.setRequestPreCallback(myCallbackFunction); i used new  ArcGISTiledMapServiceLayer(this.baseMapURL,{ id:'baseMap'}) to created a ArcGISTiledMapServiceLayer object,but the tile image loaded failed,because the callback headers setting didn't work, by the way,the api version is 3.3,if there is a solution without update version to 4.X?Look forward to your reply! thanks!

0 Kudos