Hide Table of Contents
View DataReviewer - Reviewer Results sample in sandbox
DataReviewer - Reviewer Results


ArcGIS Data Reviewer stores features and rows as results in a Reviewer dataset. Results represent a feature or row that has been marked as an anomaly by validation or manual inspection. ReviewerResultsTask has functions that retrieve non-spatial feature sets of these results. ReviewerResultsTask differs from DashboardTask in that DashboardTask retrieves aggregate information about data quality from a Reviewer workspace. This sample uses the getResults function to return a feature set of Reviewer Results. A callback function defined in a deferred object receives the results. The live sample retrieves dashboard statistics from a hosted instance of Data Reviewer for Server.


<!DOCTYPE html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Reviewer Results Sample</title>    
<link rel="stylesheet" href="https://js.arcgis.com/3.20/dijit/themes/claro/claro.css">
<link rel="stylesheet" href="https://js.arcgis.com/3.20/dojox/grid/resources/claroGrid.css">
<script src="https://js.arcgis.com/3.20/"></script>
.reviewerForm {
	width: 530px;
	font-size: .7em;
	font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
.reviewerForm input, .reviewerForm textarea{
	padding: 5px;
	width: 371px;
	margin: 0px 0px 10px 0px;
	border: 2px solid #CCC;
	font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
.submitButton {
	float: right;
	padding: 5px;
	width: 150px;
	font-size: 1.1em;
	border: 2px solid #CCC;
	margin: 0px 0px 10px 0px;
	vertical-align: top;
	font-size: 1.0em;
	font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
.reviewerForm select{
	padding: 5px;
	width: 385px;
	margin: 0px 0px 10px 0px;
	border: 2px solid #CCC;
.reviewerForm label {
	float: left;
	text-align: right;
	margin-right: 15px;
	width: 130px;
	padding-top: 5px;
.reviewerGrid {
   font-size: 0.75em;
   font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
//This should point to the Data Reviewer soe
var drsSoeUrl = "https://datareviewer.arcgisonline.com/arcgis/rest/services/Samples/reviewerDashboard/MapServer/exts/DataReviewerServer";
//array of return fields
var returnFields = [];
//Records per page
var recordsPerPage;
], function(parser, dom, on, array, ItemFileReadStore, 
 DataGrid, MultiSelect, ReviewerResultsTask,
 GetResultsQueryParameters,registry) {
    // specify proxy for request with URL lengths > 2k characters
    esriConfig.defaults.io.proxyUrl = "/proxy/";
    // create ReviewerResultsTask instance 
    var reviewerResultsTask = new ReviewerResultsTask(drsSoeUrl);
    //get list of return field names
    var fieldNames =  reviewerResultsTask.getResultsFieldNames();

    //Populate field names to be returned by Get Results operation
    array.forEach(fieldNames, function(field, i) {
        dom.byId("fieldNamesCombo")[i] = new Option(field, i);
    //Click event of previousButton button
    on(dom.byId("previousButton"), "click", loadPreviousPage);
    //Click event of nextButton button
    on(dom.byId("nextButton"), "click", loadNextPage);
    //Click even of getResultsButton button
    on(dom.byId("getResultsButton"), "click", populateDataGrid);

    function populateDataGrid() {
        // Get the number of records per page
        recordsPerPage = parseInt(dom.byId("RecordsPerPage").value);
        //Get Selected fields from the list box
        var selectItem = registry.byId('fieldNamesCombo').getSelected();
        if(isNaN(recordsPerPage) || recordsPerPage < 1){
           alert("Please fill out records per page.");
        if(recordsPerPage > 1000){
          alert("Records per page can not be greater than 1000.");
        if(selectItem.length < 1){
            alert("Please select return fields.");
        //Generate grid layout and returnFields based on fields selected in the list box
        var layout = [];
        returnFields = [];
        array.forEach(selectItem, function(option) {
            var selectedIndex =  option.value;
            layout.push({field:fieldNames[selectedIndex], name:fieldNames[selectedIndex]});	
        //set default page number for the grid
        dom.byId('lblPageNumber').innerHTML = 1;
        //show the grid with a loading message and populate it
        loadDataInGrid("", layout);
    function loadDataInGrid(moveType, layout) {
        showGrid(true, 'loading');
        var queryParameters=GetQueryParameters(moveType);
        // call getResults to retrieve the results stored in the reviewer workspace.
        var deferred = reviewerResultsTask.getResults(queryParameters);            
        // we're using dojo deferred 'then' function to set callback and errback functions
        deferred.then(function(response) {
            // map attributes from features to items array to populate dataGrid
            var items = array.map(response.featureSet.features, function(feature) {
            return feature.attributes;
            // create a dojo ReadStore
            var store = new ItemFileReadStore({
              data : {
                 items : items
            // set the store in the DataGrid, this will populate the datagrid with the reviewer results
            //update current page number label
            if(moveType == "previous" && (parseInt(dom.byId('lblPageNumber').innerHTML) > 1)){
                dom.byId('lblPageNumber').innerHTML =  parseInt(dom.byId('lblPageNumber').innerHTML) - 1;
            else if(moveType == "next") {
                dom.byId('lblPageNumber').innerHTML =  parseInt(dom.byId('lblPageNumber').innerHTML) + 1;
        }, function(err) {
           if(moveType == "next" && (err.message.indexOf("No results returned for specified query:") === 0)){
                alert("You are already at the last page.");	
                alert("Error retrieving reviewer results: " + err.message);
    function GetQueryParameters(moveType){
        var queryParameters = new GetResultsQueryParameters();
        queryParameters.pageSize = recordsPerPage;
        if(moveType == "previous" && (parseInt(dom.byId('lblPageNumber').innerHTML) > 1)){
            queryParameters.pageNumber = parseInt(dom.byId('lblPageNumber').innerHTML) - 2;
        else if(moveType == "next"){
            queryParameters.pageNumber = parseInt(dom.byId('lblPageNumber').innerHTML);
            queryParameters.pageNumber = 0;
        queryParameters.returnFields = returnFields;
        return queryParameters;
    //load next page
    function loadNextPage() {
    //load previous page
    function loadPreviousPage(){
        if(parseInt(dom.byId('lblPageNumber').innerHTML) == 1) {
            alert("You are already at the first page.");
            loadDataInGrid("previous", "");	
    //handle grid visibility
    function showGrid(show,message) {
        reviewerResultsGrid.showMessage(message || "");
        dom.byId('gridDiv').style.visibility = show ? "visible" : "hidden";
<body class="claro">
    <h2 align="center">Get Reviewer Results with Paging Sample</h2>
    <div style="width:100%; overflow-x: auto;" >
        <div style="padding: 0px 20px 0px 20px; float:left;">
            <div class="reviewerForm" >
                <label for="RecordsPerPage">Records per page:</label>
                <input type="number" id="RecordsPerPage" placeholder="valid values are from 1 to 1000"/>
                <label for="fieldNamesCombo">Return fields:</label>
                 <select class ="reviewerMultiSelect" id="fieldNamesCombo" data-dojo-type="dijit/form/MultiSelect"></select>
                <label for="getResultsButton"></label>
                <button id="getResultsButton" class="submitButton">Get Results</button>
    <div id = "gridDiv" style="width: 100%; overflow-x: auto;visibility: hidden" class="reviewerGrid">
        <button id="previousButton"> < </button>
        <label id = "lblPageNumber" >1</label>
        <button id="nextButton"> > </button>	
        <table data-dojo-id="reviewerResultsGrid" data-dojo-type="dojox/grid/DataGrid" autoheight="true" autowidth="true"></table>