dgrid refresh array / store problems

1387
2
Jump to solution
01-28-2013 12:52 PM
DavidJenkins
New Contributor III
I have a rather large application accessing several arcgis server services (10.1).  The application's intent is to query these large data warehouses and allow the users visualize their content.  Development went fine and I published a nice app that has a large audience and continues to develop with time.  I use dgrid (3.2/1.7) to display query results in tabular format to accompany the maps.  I thought it worked well until one of my users pointed out an apparent issue:

"Though the table (dgrid) appears to return the correct number of records, the data within it is incorrect..."

After investigating the issue, the user was correct.  I re-created the issue in a sample posted below.  It appears that the query executes correctly, the number of records counted in the array is correct, the number of rows displayed in the dgrid is correct, but the data is not.

If you use the sample provided (no map) you see that upon executing the button (submit filter) without anything in the text box, that the query responds and returns the result to the dgrid as expected.  Now, enter "or" (without quotes) into the textbox and submit again.  You'll see that the query executes, reports the correct number of records (7) and dgrid displays the correct number of rows (7).  However,...  within the list of state names, none of them contain the string "or".  Alaska, Connecticut, Hawaii, Maine, Massachusetts, New Hampshire, Rhode Island...  The results are the first 7 rows of the previous query, the array was not updated in the grid.

Now.. click on the table header "State Name"... "Poof!"  They appear!!!

Can someone look at my code and tell me if I'm overlooking something or misunderstanding the appropriate use of dgrid?

<!DOCTYPE HTML> <html xmlns="http://www.w3.org/1999/xhtml"> <head>   <meta charset="utf-8">   <link rel="stylesheet" href="http://serverapi.arcgisonline.com/jsapi/arcgis/3.2/js/dgrid/css/dgrid.css" />   <link rel="stylesheet" href="http://serverapi.arcgisonline.com/jsapi/arcgis/3.2/js/dgrid/css/skins/tundra.css" />     <script src="http://serverapi.arcgisonline.com/jsapi/arcgis/3.2/"></script>   <script>          require(["esri/layers/FeatureLayer", "dijit/layout/BorderContainer", "dijit/layout/ContentPane", "dijit/form/Button"],     function(FeatureLayer){               window.sitesUrl = "http://server.arcgisonline.com/ArcGIS/rest/services/Demographics/USA_Median_Net_Worth/MapServer/4";         window.siteFields = ["OBJECTID", "NAME"];                          window.sitesFL = new esri.layers.FeatureLayer(window.sitesUrl, {             "id": "sites",             "mode": 1, // ONDEMAND             "outFields": window.siteFields         });            })             function executeSite() {       require(["dgrid/Grid", "dojo/_base/array"], function(Grid, array) {               //define query task               siteQueryTask = new esri.tasks.QueryTask(window.sitesUrl);               //define query params               siteQuery = new esri.tasks.Query();               siteQuery.returnGeometry = true;               siteQuery.outFields = window.siteFields;                                 siteQuery.where = "NAME LIKE '" + dojo.byId('stateText').value + "%'" + " OR " + "NAME LIKE '%" + dojo.byId('stateText').value + "%'";                                      siteQueryTask.execute(siteQuery, function(results) {                                     var siteData = [];                                         var siteData = array.map(results.features, function(feature){                         return {                             "id": feature.attributes[window.siteFields[0]],                             "NAME": feature.attributes[window.siteFields[1]]                                                                  }                     });                                         var mySiteGrid = new Grid({                         columns: {                           "id": "ZOOM",                           "NAME": "State Name"                         }                                         }, "siteGrid");                                         mySiteGrid.renderArray(siteData);                     dojo.byId("siteInfo").innerHTML = siteData.length + " records found";                               });           });        }       </script>  </head>  <body class="tundra">     <div id="container" dojotype="dijit.layout.BorderContainer" design="headline" gutters="false" style="width:100%; height:100%;">            <div dojotype="dijit.layout.ContentPane" id="main" region="center">                           <div dojotype="dijit.layout.ContentPane" >                               <b><i><div id="siteInfo"></div></i></b>                               <button dojoType="dijit.form.Button" align="left" onclick="executeSite();">           Submit Filter         </button>                                <br />State Name<br />          <input type="dijit.form.TextBox" id="stateText" value=""/>                                                                                                                                                                             </div>     <div id="siteGrid"></div>      </div>   </div> </body>  


Thank you in advance.
0 Kudos
1 Solution

Accepted Solutions
ReneRubalcava
Frequent Contributor
Taking a guess as to the why, the first time you make the grid, it's bound to the HTML dom node or "siteGrid". When you execute it again, you are trying to bind a new Grid to the same node, but like widgets, I think the Grid is already bound, so it can't properly refresh the data. Dojo keeps track of these elements.

So, at first I tried a mySiteGrid.refresh(), but nope, the previous dom elements that make up the Grid are still there. So I moved the mySiteGrid declaration out of scope of the function, then do a check if it's null, if it is, initialize it, then refresh the old data and load new data.

    var mySiteGrid;     function executeSite() {       require(["dgrid/Grid", "dojo/_base/array"], function(Grid, array) {               //define query task               siteQueryTask = new esri.tasks.QueryTask(window.sitesUrl);               //define query params               siteQuery = new esri.tasks.Query();               siteQuery.returnGeometry = true;               siteQuery.outFields = window.siteFields;                                 siteQuery.where = "NAME LIKE '" + dojo.byId('stateText').value + "%'" + " OR " + "NAME LIKE '%" + dojo.byId('stateText').value + "%'";                                      siteQueryTask.execute(siteQuery, function(results) {                                     var siteData = [];                                         var siteData = array.map(results.features, function(feature){                         return {                             "id": feature.attributes[window.siteFields[0]],                             "NAME": feature.attributes[window.siteFields[1]]                                                                  }                     });      if (!mySiteGrid) {       mySiteGrid = new Grid({        columns: {          "id": "ZOOM",          "NAME": "State Name"        }                           }, "siteGrid");      }      mySiteGrid.refresh();                     mySiteGrid.renderArray(siteData);                     dojo.byId("siteInfo").innerHTML = siteData.length + " records found";                               });           });        }   


This worked.

I'm pretty sure trying to rebind a DGrid to a dom element that already has the DGrid is what was causing your issue.

View solution in original post

0 Kudos
2 Replies
ReneRubalcava
Frequent Contributor
Taking a guess as to the why, the first time you make the grid, it's bound to the HTML dom node or "siteGrid". When you execute it again, you are trying to bind a new Grid to the same node, but like widgets, I think the Grid is already bound, so it can't properly refresh the data. Dojo keeps track of these elements.

So, at first I tried a mySiteGrid.refresh(), but nope, the previous dom elements that make up the Grid are still there. So I moved the mySiteGrid declaration out of scope of the function, then do a check if it's null, if it is, initialize it, then refresh the old data and load new data.

    var mySiteGrid;     function executeSite() {       require(["dgrid/Grid", "dojo/_base/array"], function(Grid, array) {               //define query task               siteQueryTask = new esri.tasks.QueryTask(window.sitesUrl);               //define query params               siteQuery = new esri.tasks.Query();               siteQuery.returnGeometry = true;               siteQuery.outFields = window.siteFields;                                 siteQuery.where = "NAME LIKE '" + dojo.byId('stateText').value + "%'" + " OR " + "NAME LIKE '%" + dojo.byId('stateText').value + "%'";                                      siteQueryTask.execute(siteQuery, function(results) {                                     var siteData = [];                                         var siteData = array.map(results.features, function(feature){                         return {                             "id": feature.attributes[window.siteFields[0]],                             "NAME": feature.attributes[window.siteFields[1]]                                                                  }                     });      if (!mySiteGrid) {       mySiteGrid = new Grid({        columns: {          "id": "ZOOM",          "NAME": "State Name"        }                           }, "siteGrid");      }      mySiteGrid.refresh();                     mySiteGrid.renderArray(siteData);                     dojo.byId("siteInfo").innerHTML = siteData.length + " records found";                               });           });        }   


This worked.

I'm pretty sure trying to rebind a DGrid to a dom element that already has the DGrid is what was causing your issue.
0 Kudos
DavidJenkins
New Contributor III
Thank you very much, that worked well. 

At one point I did implement a check to see if the object existed, if it did, destroy it and re-create it but that didn't work either.  I would never have thought to declare the grid outside of the function.  I still haven't quite fully realized that change and what it means to the app.  I was under the impression that one of the results of moving to AMD is the elimination of global variables.

Anyway, good work thanks again!
0 Kudos