Showing posts with label Promise. Show all posts
Showing posts with label Promise. Show all posts

Monday, 22 April 2019

JET - fetch all rows from ADF BC REST service

JET: 6.0.0
Source: GitHub

Oracle JET and ADF BC REST have a fantastic work relation. Each power-house seems to complement the other. As an example, JET's pagination module handles the entire responsibility of breaking up the data into chunks and fetches them as necessary, as and when the user navigates through the pages. The developer just needs to specify the page-size, and the framework divides the entire row-count into chunks of page-size, and uses the offset value to incrementally fetch the newer sets of data.

However, there might be times, when you need the entire data-set inside your JS array, without having the luxury of any pagination to do the job incrementally for you. In such cases, the below technique might help.

Step 1: Fire a rest call with totalResults=true, to fetch the total row count of your rest query.


Step 2: Use this row count value, and divide it into multiple chunks. E.g., I have decided to fetch 50 records at a time. Hence, the offset values would be 0, 50, 100. Each URL is sent to our helper method, which returns a promise.

You may set the limit value as a configurable option

Offset 0 fetches rows 1 to 50, offset 50 fetches 51 to 100, offset 100 fetches 101 to 107.

Step 3: I now have an array of promises, which I can evaluate all at once.



And there you go. You have the entire data set at your disposal. You may further optimise this process as per your need.

If you are familiar with ADF business components, a similar technique is used there as well. The developers configure the fetch-size for the view objects. The ADF framework gets a hold of the total row count, and then uses these information to decide on the number of database server trips and fetch the required number of rows per trip.

In the end, there are a few points quite worth mentioning:
1. A very high limit value may serve your purpose, but that is just a random guess, and did not seem very efficient to me.
2. This is just a technique to showcase an interesting use of totalResults and offset features of ADF BC REST. Large data sets should always be handled through a pagination or load-more-on-scroll mode. Not only are they performance boosters, they are also helpful from the UX perspective. So unless you really need to work on the entire data set at once (for displaying a chart maybe), this is not recommended.

Cheers!

Wednesday, 2 January 2019

JET - Handling table selection with Promise

JET: v6.0.0
Source: GitHub

This article explores a simple technique to get the selected data from an ojTable component. The click or selection event on an ojTable can be handled in multiple ways, and this concept can be extended to any event - onOjBeforeCurrentRow or onSelectionChanged.

Be it any of the above events, the data from the selection event on ojTable is of the same type. It consists of an array of objects, each of which has a startIndex and an endIndex. For a table supporting multiple selection, these values denote the index of the first selected row and the last selected row (respectively). For single selection, the start and end index is same. The selection object also consists of the Key attribute of the selected rows.

An interesting note: for multiple selection, when consecutive rows are selected - say row numbers 2 and 3 - the selection data generates a consolidated object, where start index is 2 and end index is 3. 


But, when we select random rows - say 0, 2 and 3 - the selection data event intelligently generates a consolidated array object - one with start index 0 and end index 0, and another with start index 2 and end index 3.


Using these start and end indices, we can locate the data at these indices inside the paging or array collection data source.

However, when we get the data at an index, using datasource.at, we get back a promise. If we have to loop through all the selected indices and get the data at each node, we would need resolve each individual promise. By the time we do this, the synchronous code will be completed and we will not have any way to handle the promise data.

The solution to this problem is to get all these promises in an array, and then resolve them all at once, using Promise.all.

I have a TableUtils js, which creates this array of promises.


This array of promises is handled all at once, and the data is extracted from the resulting array.



Cheers!