Archive | REST Service RSS for this section

Gridx in XPages – 4: Loading Live Data via a REST Service

In the last post, I showed how to get a simple Gridx grid up and running in an XPages application with hard-coded data. In this post, I’ll show how to load live data via a REST service, which requires a different type of data store and cache.

Gridx Series

Gridx in XPages — Entire Series

Providing the Data via a REST Service

My test application uses a subset of data from the Fakenames.nsf database from David Leedy’s XPages Cheatsheet.

I created an XPage named X_REST and added a viewJsonService REST service to surface data from the ByName-First view.

<xe:restService id="restJsonService" pathInfo="gridData">
  <xe:this.service>
    <xe:viewJsonService defaultColumns="true" viewName="ByName-First" var="dataRow">
    </xe:viewJsonService>
  </xe:this.service>
</xe:restService> 

The defaultColumns attribute is set to true, so it will automatically include all columns from the view in the output.

The pathInfo attribute is set to gridData, so I can reference the REST service from within the application via this URL: X_REST.xsp/gridData

Here’s a sample of the REST service output (the first row from the view):

{
  "@entryid":"1-4030FB42B37B397785257D87004680BC",
  "@unid":"4030FB42B37B397785257D87004680BC",
  "@noteid":"FCE",
  "@position":"1",
  "@siblings":1298,
  "@form":"fUserName",
  "firstname":"Adam",
  "lastname":"Gonzales",
  "address":"392 Shinn Street",
  "city":"New York",
  "state":"IL",
  "zip":10021,
  "country":"US",
  "address":"392 Shinn Street",
  "password":"nae1nae7Su",
  "phone":"212-774-8218",
  "mothersmaiden":"Shah",
  "birthday":"1952-02-08T11:53:39Z",
  "cctype":"MasterCard",
  "ccnumber":5436047424022667,
  "cvv2":830,
  "ccexpires":"2\/2009",
  "national":"051-68-8261",
  "ups":"1Z 82F 8A5 82 1526 912 5",
  "occupation":"Substance abuse and behavioral disorder counselor"
}

All of the attributes beginning with @ are system columns that are automatically included. (You can refine which system columns are included via the systemColumns attribute of the REST service.)

The rest of the attributes are based on columns in the view.

Updated Gridx Using Live Data

In order to use live data, there are two primary changes to make to the grid code:

  1. Data Store
  2. Cache

Rather than using a Memory store, it changes to a JsonRest store. This includes the ability to retrieve remote data.

Since it is now using remote data (rather than hard-coded local data), we also switch the cache from synchronous to asynchronous. All you have to do is load a different cache module — no other code needs to change.

<script> require([
  "gridx/Grid", "dojo/store/JsonRest",
  "gridx/core/model/cache/Async", "dojo/domReady!"
  ], function(Grid, JsonRest, Cache) {
	  	
  var store = new JsonRest({
    idProperty: '@noteid',
    target: "X_REST.xsp/gridData"
  });
		
  var columns = [
    {id: 'first', field: 'firstname', name: 'First', width: '70px'},
    {id: 'last', field: 'lastname', name: 'Last'},
    {id: 'state', field: 'state', name: 'State', width: '40px'}
  ];
	
  grid = new Grid({ 
    id: "my_gridX", 
    cacheClass: Cache, 
    store: store, 
    structure: columns 
  });
			
  //Put it into the DOM tree. 
  grid.placeAt('gridX_Here');
  grid.startup();
	  
});
</script>

Lines 1-4 define our updated AMD loading requirements. The data store is now dojo/store/JsonRest and the cache is now gridx/core/model/cache/Async.

Lines 6-9 set up the new JsonRest store. The target attribute specifies the URL where the REST data can be retrieved. (I’ll come back to the idProperty attribute momentarily.)

Lines 11-15 define the columns for the grid. The field attribute of each column must match up with an attribute name in the REST data. In this case, it’s set up to show the first name, last name, and state columns from the underlying view.

Lines 16-25 define the Gridx object and instantiate it. None of these lines changed since the first simple example.

Using this code, we now have a Gridx grid that displays live data from our application.

Gridx 4 - Grid

Define the Unique ID

I want to call attention to line 7 in the source code above — the idProperty attribute of the JsonRest store.

Gridx requires that each row have a unique identifier. It assumes that it will find an attribute named id in each row. However, the ByName-First view does not have a unique ID column named id. This causes the grid to display data from the last row repeatedly in place of each row in the grid (presumably because all rows have no known id and, therefore, cannot be differentiated.)

The simple solution to this is to set the idProperty attribute of the store. This lets the store know how to uniquely identify each row and it allows the grid to display the data properly. I used the @noteid attribute in the example above, but you could also use @entryid, @unid, or even @position.

Data Requests

It’s interesting to note that (without me doing any configuration) the grid makes two GET calls as the page loads.

It initially loads the first 99 rows, presumably to let the grid load faster.

It then makes a second call to get the rest of the data from row 100 on. (At this point, my example has about 1300 rows. I don’t know at this point if it will break very large data sets into multiple additional calls.)

Gridx touts performance and its ability to handle large data sets. I would assume this means that it’s doing its best to both load quickly and still get the full data set locally for fast processing.

When the grid loads, I have the ability to quickly scroll through all rows.

Dojo Data Grid – Part 2: Providing the Data with a REST Service

Data grids need a data store to obtain the information to display in the grid.

An easy way to set one up with XPages by using a REST Service control, which, like the Dojo Data Grid control, is available in the Extension Library and with 8.5.3 Upgrade Pack 1. You can find it in the Data Access section of the Controls view in Domino Designer:

Grid2_1

When you add one to the page, you see this little icon on the Design tab:

Grid2_2

Configuring the REST service

Follow these steps to set up the REST service to provide the data from a view:

1. Select the REST service control and All Properties subtab of the Properties panel, go to basics > service and click the plus (+) icon and select xe:viewJsonService
Grid2_3

2. Set the contentType (basics > service > contentType) to application/json

3. Set the defaultColumns property (basics > service > defaultColumns) to true. This provides the data from all columns in the underlying view, without you having to define them individually. (You can select individual columns or define your own via the columns property, if you choose, but this is the easiest way to get all columns from the view.)

4. Select the target view in the viewName property (basics > service > viewName)

Verifying the REST service

If you set the pathInfo property of the rest service (All Properties > basics > pathInfo), you will have a way to verify the data being returned by the service. This is a very helpful tool not only for troubleshooting, but for gaining an understanding of the data structure that you’re working with.

Grid2_5

To verify the data, load the XPage that contains the REST service and include the pathInfo name in the URL, like this:

server.com/dbname.nsf/xPageName.xsp/pathInfoName

Here is an example of what you will see:

Grid2_6

The pathInfo is not required when working with the Dojo Data Grid, but it is required when consuming the REST service from another library, like ExtJS.

Creating a Custom Column

In addition to (or in lieu of) the default columns, you can define your own custom columns for the REST service. You can use this to compute values that combine information in the underlying view or even look up information from another database altogether, because you use server-side JavaScript.

In order to read data from the view entry, you will need to set the ‘var’ property of the REST service.

For example, if I wanted to add a column that combines the firstname and lastname columns from underlying view, I would need to take these steps:

  1. Set the var property of the REST service (All Properties > basics > service > var)
  2. Add a new column, but clicking the ‘+’ icon in the columns property (All Properties > basics > service > columns)
  3. Click the diamond to compute the value of the column (All Properties > basics > service > columns > restViewColumn[0] > value)
  4. Set the name of the column (this will be the way to reference the column in the grid) under All Properties > basics > service > columns > restViewColumn[0] > name
  5. Enter a script like this:
return restEntry.getColumnValue("firstname") + ' ' + restEntry.getColumnValue("lastname");

Grid2_7

Now, if you verify the REST service data, you’ll see the additional column.
Grid2_8

There does not appear to be a built-in way to get a handle to the underlying document, but you should be able to reference the unid from the view entry and use that to look up the document, should you need more information.

System Columns

The REST service also has a systemColumns property, which allows you to select system values to include with each entry. Clicking the button in the property row will bring up a dialog box with checkboxes for the options to select.

Grid2_4

Here are the options:

  • NoteID
  • UNID
  • Position
  • Read
  • Siblings
  • Descendents
  • Children
  • Indent
  • Form
  • Category
  • Response

As you can see in the screen shots earlier in this post (with the REST service data), several of these system columns are included by default: unid, noteid, position, siblings, form.

If you select one or more system columns specifically, then only the selected system columns will be included. It appears that @entryid will always be included.

Ready for the grid!

How that you have a REST service providing data, you are ready to surface the grid! Tune in next time to see how to surface your first grid.