A First Foray Into Oracle JET

Doug Gault Oracle JET 6 Comments

Now that Oracle APEX 18.1 development is winding down, code freezes are in place, and only bug fixes are being allowed to be addressed, I’ve directed my development efforts in another direction.

With the eventual goal taking the ORDS screens I created for APEX and implementing them in a forthcoming SQL-DEV Web version, I have started learning about Oracle JET.  If you don’t know much about Oracle JET yet, I’ll direct you to their official web site. But in a nutshell, Oracle Jet is a collection of JavaScript libraries working together to create a client side JavaScript application framework.

The obvious first stop for this was Oracle Jet’s own learning page. From this page I chose to start with the MOOC that the JET team had authored. I dutifully signed up for it, followed it all the way through and learned a good amount about what JET is capable of and how the development environment all hangs together.

It was at this point I started to stretch my wings by attacking a small project assigned to me by Kris Rice – Modernizing a small SQL-Developer Usage Statistics reporting app.

Big Brother is Watching (but only if you let him)

As you are likely aware, SQL-Developer (like many other software products) collects anonymous statistics about how you use it. You’re asked when you first install the software to allow the collection and it can be turned off at any time from the preferences section under Usage Reporting.

SQL Developer occasionally sends that collected information back to Oracle so that we can see how our customers are using the tool.

The data that is collected has to do with what parts of the tool are being used and what flavors of database (and which versions) are being accessed the most.

As stated in the dialog, “No personally identifiable information will be sent and the report will not affect performance.”  But if you’re at all concerned, you can read Oracle’s Privacy Policy on the Oracle Web site.

Reporting on Gathered Statistics

For quite some time there has been a relatively simple JavaScript application in place to report on the statistics gathered from SQL Developer. It was written using some of the D3.js libraries as well as some hand cranked code and a few REST calls to get the actual statistics from an Oracle Database. However the code was written and maintained by someone who has since moved to another team, so it has not been updated for quite some time. Although still working, it could benefit from a facelift and for the data to be broken down and sorted slightly differently.

A Noobs Learning Journey

Since I’m new to JET, I thought it would be a good idea to simply replicate exactly what I saw in the D3 app, in JET. This way I could make sure that the graphs looked the same and the numbers I was getting matched. Then I could go about making the changes to slice and dice the data in different ways.

Based on my experience with the MOOC, I really thought I had the grounding to do this without too much problem. After all, there were only 4 objects on the screen; two select lists, a chart and a data table. However after slightly more than a couple of frustrated days, I realized that what I didn’t know about KnockoutJS (a critical part of the JET infrastructure) was clearly “observable”!

In fact, my lack of real knowledge about KnockoutJS was holding me back. So I decided to remedy that by focusing specifically on learning knockout. I looked around at various different documents, books, courses, etc. but finally settled on a Pluralsight course by John PapaBuilding HTML5 and JavaScript apps with MVVM and Knockout. This course clarified my knowledge a lotIt took me from thinking I knew what Knockout was and how it worked, to a far better understanding of what it really does. And it even managed to help me sharpen my JavaScript skills along the way.

Full of a new sense of self confidence, I attacked the problem again and got a lot further. I was able to use REST calls from JavaScript to connect to the remote database and retrieve the data I was interested in. Thanks to the wonderful Oracle JET Cookbook, I was able to see and understand how to use Chart and Table data providers to format the data in ways the JET components were expecting it, including how to structure Chart Options objects, Series and Group Comparators for sorting, callback functions to switch from a Percentage based data set to a Usages based one, etc.

The REAL Learning Starts Here

Even though I had made tremendous progress (enough to be proud of for a JET noob), I was still getting some console errors about callback functions not being defined (even though they worked when called), had some issues with switching between tabs, problems with properly loading a 3rd party Javascript Library i was using, etc. So I sought help from one of the founding fathers of Oracle JET, John “JB” Brock. This did not go as planned.

What should have been a 30 minute troubleshooting session where John looked at the code and told me where I was being stupid, turned into a 3 hour debugging session that had us both scratching our heads for quite some time. We tried various things to make what I had done work, but in the long run we discovered that I had just done some things blatantly “wrong”.

Firstly, even though i had used the JET application template that created 4 separated “tabs” for the application, i was treating the HTML and JavaScript for each tab as a separate application in their own right. I was mistakenly using the Knockout require keyword at the top of each .js file instead of using the define keyword required for any subsidiary files.

I also had completely ignored the portions of the template that are there to help with JavaScript Promises and Promise Resolution. Meaning that I was trying to access objects before they were ready, and potentially even created.  (Note to self: Read up more on JavaScript Promises).

Second, I was trying to load my 3rd party library the old school way (by simply including it in the base HTML as a script) instead of using RequireJS to load it.

Thirdly, I had slipped back into my old JavaScript ways and, even though I had defined the appropriate variables as Knockout “Observables”, I was assigning them using  myVariable = ‘value’;  instead of correctly calling the observable as a function (i.e.  myVariable(‘value’); ), therefore destroying the observable and creating a whole new variable.

After going back and fixing those issues, everything started working much more smoothly with no console errors.

Next Steps – Refactoring

As much progress as I’ve made, there are things that need to be addressed even before I start slicing and dicing the data differently. For instance, currently the REST calls are instantiated each time you navigate to a tab. This shouldn’t need to happen as the data does not change that frequently, so I want to refactor the REST calls out so that they’re called once when the application is instantiated and then used by the individual tabs.

Also, because the displays on each tab depend on the fact that the application can reach the REST services, I’d like to disable the tabs until I know the REST data has been returned correctly and is ready to display.

I’d also want to give the user the opportunity to force a refresh of the individual data models. This would mean disabling the tab, re-executing the REST call and then re-enabling when ready.

While this sounds straight forward, It involves learning about communication between various data models that are defined in the application. While I’m sure there are structures and methods in place for just that reason, it’s going to be a whole new area of study for me.

Wish me luck and I’ll report back on that in a forthcoming post.


Comments 6

  1. Tried to pick up JET as well after finishing the MOOC. Mostly was interested in integration of any JET components into an APEX app as APEX item.

    What would be really nice is to see a blog post on this. Or maybe even an universal plugin for this (to add any component from a Cookbook to an APEX page).

    1. Post

      Hey Denis,

      Ya it would be nice to know how to integrate standard jet components into APEX. However I’m not sure there is a universal plugin that could be created to integrate them all.

      Was there a specific JET component you were looking at integrating?

      1. Sure, a list of! In example:
        – SELECT and SELECT MANY – I love the fuzzy search option a lot, I know about Select2 Plugin, but JET’s is even more powerful to my mind
        – FILE PICKER
        – And, surpisingly, TABLE and DATA GRID components – their flexibility would enable us to change the number of columns and rows of reports on-the-fly without pain (what I can’t say about the APEX report regions). It is crucial when you show a PIVOTED version of a report, and you know the number of columns only on execution time (this is still achievable with the CLASSIC REPORT region in APEX, but it leverages a PL/SQL function returing SQL functionality and looks terrible). The task is even more difficult (and not possible with standart APEX regions) when you need to refresh data periodically (let’s say every 10 seconds) and the number of columns may change. In past, to solve the problem, I integrated jQuery DataTabes plugin, but JET’s TABLE seem much more natural and well written.

        1. Just a follow-up – since I was only toying with JET, I’m not sure what are the differences of SELECT and COMBOBOX components sets, they seem pretty similar to me (and maybe it is better to have a closer look before trying to integrate on into APEX).

        2. Post

          Wow, that’s quite a list.

          The unfortunate truth is that it would be a fair amount of work to integrate these items into APEX, even as a plugin. And, knowing that each component has different attributes, methods, etc. I don’t see a way of creating a universal plugin that could incorporate these things.

          A person could do a whole blog series on what it takes to integrate APEX and JET as there are doubtless some fundamentals that need to be tackled, and then addressing each component type.

          And unfortunately I have enough on my plate that this won’t be something I can tackle.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.