Hello, can anyone guide me in a direction on how to use the esriRequest function in a Web Appbuilder Widget?
I have just started using Web AppBuilder Developer Edition. I started with extending the sample widget Demo with a button
Widget.html:
<div> <button id="gotoPosition" data-dojo-type="dijit/form/Button" type="button" data-dojo-attach-point="gotoPosition">Go to position</button> </div>
I then extended the onOpen: function() in widget.js to zoom to a position
... onOpen: function(){ console.log('onOpen'); var map = this.map; var Long, Lat; var LocPoint, point; //Go to position on(this.gotoPosition, 'click', lang.hitch(this, function(evt){ console.log('gotoPosition 2'); map.graphics.clear(); Lat = 55; Long = 15; LocPoint = new Point([Long,Lat]); map.centerAndZoom(LocPoint,17); })); }, ...
From Access data (XML) | ArcGIS API for JavaScript I found out how to use esriRequest and from Using the proxy | Guide | ArcGIS API for JavaScript how to install the proxy and finally putting it all together in one HTML file (esriRequest_xml.html) which works fine.
<!DOCTYPE html> <html> <head> <title>XML Content</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <link rel="stylesheet" href="http://js.arcgis.com/3.14/esri/css/esri.css"> <script src="http://js.arcgis.com/3.13/"></script> <script> require(["dojo/dom", "dojo/on", "dojo/dom-class", "dojo/_base/json", "dojox/xml/parser", "esri/config", "esri/request", "dojo/domReady!"], function(dom, on, domClass, dojoJson, xmlParser, esriConfig, esriRequest) { console.log('ok') esriConfig.defaults.io.proxyUrl = "/PHP_proxy/proxy.php"; var url = "url to a xml docement"; var requestHandle = esriRequest({ "url": url, "handleAs": "xml" }); requestHandle.then(requestSucceeded, requestFailed); function requestSucceeded(response, io){ document.write("Succes"); //do something with the xml data } function requestFailed(error, io){ document.write("Fail"); } }); </script> </head> <body> </body> </html>
I then tried to put the javascript code from esriRequest_xml.html into the onOpen: function() but this resulted in the error "Uncaught TypeError: Cannot read property 'io' of undefined" Maybe because of wrong scope?, but don't know how to fix this. Can anyone guide me how to get esriRequest to work?
Solved! Go to Solution.
Mathias,
Try this:
define([ /*rearranged your requires two where out of place and domReady should always be last*/ 'dojo/_base/declare', 'jimu/BaseWidget', "dojo/on", 'dojo/_base/lang', "esri/graphic", "esri/geometry/Point", "dojo/dom", "dojo/data/ItemFileReadStore", "dijit/form/ComboBox", "dojo/_base/json", "dojo/dom-class", "dojox/xml/parser", "esri/config", "esri/request", "dojo/domReady!" ], function( declare, BaseWidget, on, lang, Graphic, Point, dom, ItemFileReadStore, ComboBox, dojoJson, domClass, xmlParser, esriConfig, esriRequest ) { //To create a widget, you need to derive from BaseWidget. return declare([BaseWidget], { // DemoWidget code goes here baseClass: 'jimu-widget-demo', postCreate: function() { this.inherited(arguments); console.log('postCreate'); }, startup: function() { this.inherited(arguments); console.log('startup'); //ComboBox til Ejerlavnavn /*var store; store = new ItemFileReadStore({ url: "ejerlav.json" }); var combo = new ComboBox({ store: store, pageSize: "10" }, dom.byId('EjerlavComboBox')); combo.startup();*/ }, onOpen: function(){ console.log('onOpen'); var map = this.map; var Long, Lat; var LocPoint, point; //Go to position on(this.gotoPosition, 'click', lang.hitch(this, function(evt){ console.log('gotoPosition '); map.graphics.clear(); //WAB already handles the proxy for you so this is not needed //This line creates the error: Uncaught TypeError: Cannot read property 'io' of undefined //esriConfig.defaults.io.proxyUrl = "/PHP_proxy/proxy.php"; var url = "your xml url"; var requestHandle = esriRequest({ "url": url, "handleAs": "xml" }); requestHandle.then(requestSucceeded, requestFailed); function requestSucceeded(response, io){ //do something with the xml data console.info(response, io); } function requestFailed(error, io){ console.info(error, io); } //Lat = this.EjerlavTextBox.value; //Long = this.MatrNrTextBox.value; Lat = 55; Long = 15; LocPoint = new Point([Long,Lat]); map.centerAndZoom(LocPoint,17); })); }, onClose: function(){ console.log('onClose'); }, onMinimize: function(){ console.log('onMinimize'); }, onMaximize: function(){ console.log('onMaximize'); }, onSignIn: function(credential){ /* jshint unused:false*/ console.log('onSignIn'); }, onSignOut: function(){ console.log('onSignOut'); } }); });
Mathias,
Try this:
define([ /*rearranged your requires two where out of place and domReady should always be last*/ 'dojo/_base/declare', 'jimu/BaseWidget', "dojo/on", 'dojo/_base/lang', "esri/graphic", "esri/geometry/Point", "dojo/dom", "dojo/data/ItemFileReadStore", "dijit/form/ComboBox", "dojo/_base/json", "dojo/dom-class", "dojox/xml/parser", "esri/config", "esri/request", "dojo/domReady!" ], function( declare, BaseWidget, on, lang, Graphic, Point, dom, ItemFileReadStore, ComboBox, dojoJson, domClass, xmlParser, esriConfig, esriRequest ) { //To create a widget, you need to derive from BaseWidget. return declare([BaseWidget], { // DemoWidget code goes here baseClass: 'jimu-widget-demo', postCreate: function() { this.inherited(arguments); console.log('postCreate'); }, startup: function() { this.inherited(arguments); console.log('startup'); //ComboBox til Ejerlavnavn /*var store; store = new ItemFileReadStore({ url: "ejerlav.json" }); var combo = new ComboBox({ store: store, pageSize: "10" }, dom.byId('EjerlavComboBox')); combo.startup();*/ }, onOpen: function(){ console.log('onOpen'); var map = this.map; var Long, Lat; var LocPoint, point; //Go to position on(this.gotoPosition, 'click', lang.hitch(this, function(evt){ console.log('gotoPosition '); map.graphics.clear(); //WAB already handles the proxy for you so this is not needed //This line creates the error: Uncaught TypeError: Cannot read property 'io' of undefined //esriConfig.defaults.io.proxyUrl = "/PHP_proxy/proxy.php"; var url = "your xml url"; var requestHandle = esriRequest({ "url": url, "handleAs": "xml" }); requestHandle.then(requestSucceeded, requestFailed); function requestSucceeded(response, io){ //do something with the xml data console.info(response, io); } function requestFailed(error, io){ console.info(error, io); } //Lat = this.EjerlavTextBox.value; //Long = this.MatrNrTextBox.value; Lat = 55; Long = 15; LocPoint = new Point([Long,Lat]); map.centerAndZoom(LocPoint,17); })); }, onClose: function(){ console.log('onClose'); }, onMinimize: function(){ console.log('onMinimize'); }, onMaximize: function(){ console.log('onMaximize'); }, onSignIn: function(credential){ /* jshint unused:false*/ console.log('onSignIn'); }, onSignOut: function(){ console.log('onSignOut'); } }); });
Hi Robert, thank you very much it works now
I can see you moved "dojo/domReady! to the end of the define list. Was this what caused my problem?
But if I want to access xml documents from at different domain I still need the line esriConfig.defaults.io.proxyUrl = "/PHP_proxy/proxy.php"; If I remove the line I get the error: "esri.config.defaults.io.proxyUrl is not set. If making a request to a CORS enabled server, please push the domain into esri.config.defaults.io.corsEnabledServers". You mentioned that WAB takes care of this for me, but not in my case. Should I some where in other Web AppBuilder files configure this?
/Mathias
Mathias,
Yes it was the issue with the location of the domReady in your code that threw off the synchronization of your requires and your vars. WAB has a NodeJS proxy setup when you are working in builder. Once you deploy your app then you have to setup a proxy if you are going to use one and specify its url in the main config.json If you need to use a specific proxy while in builder for your app then you can set it in the main config.json for that app just like you would when you deploy the app. Open your apps config.json (i.e. [install dir]\server\apps\[app#]\config.json). Scroll to the bottom of that file and find this section:
"httpProxy": { "useProxy": true, "url": "/proxy.js" },
and change it to:
"httpProxy": {
"useProxy": true,
"url": "/PHP_proxy/proxy.php"
},
Robert
I never would have thought that the position of domReady was the problem, but now I know that. I got it to work fine with adding the proxy to config.json.
Thank you very much for your help.
/Mathias