[Progress News] [Progress OpenEdge ABL] Quick Corticon.js Applications with React Native

Not open for further replies.

David Xiao

React Native comes with great features and integrates nicely with the JavaScript library that is Corticon.js. Building a new mobile application from the ground up with a Decision Service is both intuitive and quick.

Whether you're deciding if Corticon.js is a good fit for your product, or you're looking to use Corticon in a new way, you may be tasked with writing a quick proof of concept application.

The first decision to make is what kind of application. Your first thought might be to write a web application. After all, Corticon.js is a JavaScript library. But what about other possibilities? How about a mobile application?

It might appear daunting at first to consider writing a mobile application as your proof of concept. Especially when considering that it is fairly common for someone on your team to have some level of JavaScript experience, but far less common to have someone experienced in both Android and iOS development.

And that's where React Native really shines. For a Full Stack Developer like me who spends all their time in JavaScript land, being able to use JavaScript in lieu of Java and Swift really makes the task much more manageable. Not only do you not have to learn or brush up on Java Android or Swift iOS development, but you don't have to spend the time to setup both development environments. And you get both a native feeling Android and iOS app without worrying about each individually.

Exporting JavaScript Rules as Node Package

Integrating Corticon.js as a local Decision Service is also exceedingly simple as a result. Corticon.js Studio lets you export your Decision Service as a single bundled JavaScript file. So all you have to do to add your local Decision Service is require it like so:

const myDecisionService = require('./decisionServiceBundle.js')

But before I jump into more details about how to integrate Corticon into your new React Native application, I would like to talk about some of the neat benefits of React Native.


It goes without saying that React.js is the foundation of React Native and as one of the three most popular JavaScript frameworks (alongside Angular and Vue), React has all of the top qualities you could hope for. It handles updating your view intuitively and efficiently without imposing much of a burden on how you design and organize your application. I won't go too much into React as a JavaScript framework, but I would like to highlight what stood out to me as I was working with React.

For one, React is based around Components, with each component having its own file. One file, meaning that the markup, JavaScript and CSS are all in one location. And while that might seem like a recipe for unreadable code, in practice not having three separate files for each component each with a couple blocks of code is a nice plus, especially in the case of simple demo applications.

Also, learning new syntax and quirks of a framework is usually half the challenge. However, personally I found React's syntax far more intuitive than Angular's and other JavaScript frameworks'. There was always an elegant solution and syntax for all of the common challenges that arise in a simple application.

Want to conditionally style some markup?

[ICODE]<[/ICODE][ICODE]View[/ICODE] [ICODE]style={someCondtion ? styleA : styleB}/>[/ICODE]
Want to hide some of your markup based on some criteria?

[ICODE]{someCondition && <[/ICODE][ICODE]Text[/ICODE][ICODE]>Your Markup</[/ICODE][ICODE]Text[/ICODE][ICODE]>}[/ICODE]
And while most frameworks provide some way to do most things, both of the examples above are very readable and intuitive. In fact, when I first started learning web development, I tried exactly what React allows you to do, and was disappointed to find that you couldn't use conditions to style the markup with vanilla JavaScript/HTML.

Quick Setup and Out of the Box Functionality

If you have Node already installed, setup for React Native itself really is just one npm command to download the command line tool.

Most of the real setup time is getting an emulator for Android or iOS so you can view your application. Admittedly there can be some snags (I'm looking at you Android SDK license agreement) in getting this to work on your machine, but the same setup would be required if you were writing Android or iOS code directly.

All in all, I had the starter app that comes with React Native up and running in an Android Emulator within a couple hours. Running npx react-native init AwesomeProject will setup your project directory and includes a number of useful utilities. This includes Watchman which triggers rebuilds when you modify a project file, definitely a great time saver!

Integrating Corticon into Your Shiny New Mobile Application

Alright here's the moment you were waiting for. How exactly do we call to and handle the response from the Decision Service?

Invoking the Decision Service

Calling the Decision Service from your React Native application is simple as well. Just pass your JSON payload to the 'execute' method on the Decision Service object:

Forming the Payload

The JSON payload contains all the objects the Decision Service will use to determine which rules to execute. The easiest way to see how you should form your payloads is to use Corticon.js Studio.

Exporting JavaScript Payload from Tester

Inside your Corticon.js Studio project, start with a new or existing test file. Inside the input panel you can form your payload by drag and dropping items from your Rule Vocabulary. Once you are ready, you can export your payload in JSON format by right clicking your input and selecting 'Export JSON'. This will add all necessary attributes and metadata for you!

An example payload looks like this:


[ICODE]02.[/ICODE][ICODE]    [/ICODE][ICODE]"__metadataRoot": {},[/ICODE]

[ICODE]03.[/ICODE][ICODE]    [/ICODE][ICODE]"Objects": [{[/ICODE]

[ICODE]04.[/ICODE][ICODE]        [/ICODE][INDENT][ICODE]"Name": "Some Name"[/ICODE][/INDENT]

[ICODE]05.[/ICODE][ICODE]        [/ICODE][INDENT][ICODE]"Nested Object": {[/ICODE][/INDENT]

[ICODE]06.[/ICODE][ICODE]            [/ICODE][INDENT][ICODE]"price": 53900,[/ICODE][/INDENT]

[ICODE]07.[/ICODE][ICODE]            [/ICODE][INDENT][ICODE]"name": "BMW 5 Series",[/ICODE][/INDENT]

[ICODE]08.[/ICODE][ICODE]            [/ICODE][INDENT][ICODE]"__metadata": {[/ICODE][/INDENT]

[ICODE]09.[/ICODE][ICODE]                [/ICODE][INDENT=2][ICODE]"#type": "Cars.Car",[/ICODE][/INDENT]

[ICODE]10.[/ICODE][ICODE]                [/ICODE][INDENT=2][ICODE]"#id": "Cars.Car_id_1"[/ICODE][/INDENT]


[ICODE]12.[/ICODE][ICODE]            [/ICODE][INDENT][ICODE]"manufacturer": "BMW"[/ICODE][/INDENT]


[ICODE]14.[/ICODE][ICODE]        [/ICODE][INDENT][ICODE]"__metadata": {[/ICODE][/INDENT]

[ICODE]15.[/ICODE][ICODE]            [/ICODE][INDENT][ICODE]"#type": "User",[/ICODE][/INDENT]

[ICODE]16.[/ICODE][ICODE]            [/ICODE][INDENT][ICODE]"#id": "User_id_1"[/ICODE][/INDENT]


[ICODE]18.[/ICODE][ICODE]        [/ICODE][INDENT][ICODE]"birthDate": "1990-12-25"[/ICODE][/INDENT]


Handling the Response

You've formed your payload and sent it off to your Decision Service. Now you have to think about how you want to handle the response. First and foremost, there's one big decision to make—do you want to handle the response Synchronously or Asynchronously. Since it's a local Javascript Library, the response time should be minimal. So your first thought might be that Synchronously is the clear winner.

However, writing your response handler Asynchronously opens up the door to hosting your Decision Service up in the Cloud, for example in AWS Lambda or Azure just to name a few. Also you never know how large your ruleset will eventually become, and making the JavaScript thread wait on a synchronous Decision Service call could come back to bite you.

In either case, here's the code for both. I have split off the response handler into its own function.

[ICODE]// Response Handler[/ICODE]

[ICODE]let responseHandler = (result) => {[/ICODE]

[ICODE]  [/ICODE][ICODE]// The Decision Service Status code. Always check if status == 'success'[/ICODE]

[ICODE]  [/ICODE][ICODE]if[/ICODE] [ICODE](result.status == [/ICODE][ICODE]'success'[/ICODE][ICODE]) {[/ICODE]

[ICODE]    [/ICODE][ICODE]// Get all Objects of a certain type[/ICODE]

[ICODE]    [/ICODE][ICODE]let cars = result.Objects.filter(object => object.__metadata[[/ICODE][ICODE]"#type"[/ICODE][ICODE]] == [/ICODE][ICODE]'Cars.Car'[/ICODE][ICODE]);[/ICODE]


[ICODE]    [/ICODE][ICODE]// Or Perhaps find a specific Object[/ICODE]

[ICODE]    [/ICODE][ICODE]let car = result.Objects.find(objects => object.__metadata[[/ICODE][ICODE]"#type"[/ICODE][ICODE]] == [/ICODE][ICODE]'Cars.Car'[/ICODE][ICODE])[/ICODE]


[ICODE]    [/ICODE][ICODE]// Check some condition[/ICODE]

[ICODE]    [/ICODE][ICODE]if[/ICODE] [ICODE](cars.length) {[/ICODE]

[ICODE]      [/ICODE][ICODE]// Then update your React Native Application State or Props to change what you render[/ICODE]

[ICODE]      [/ICODE][ICODE]this[/ICODE][ICODE].setState({numCars: cars.length});[/ICODE]



[ICODE]  [/ICODE][ICODE]} [/ICODE][ICODE]else[/ICODE] [ICODE]{ [/ICODE][ICODE]// there's an error[/ICODE]


[ICODE]    [/ICODE][ICODE]//handle error[/ICODE]

[ICODE]    [/ICODE][ICODE]console.log(result.description);[/ICODE]




[ICODE]// Synchronous Call[/ICODE]



[ICODE]// Asynchronous Call[/ICODE]

[ICODE]let result = [/ICODE][ICODE]new[/ICODE] [ICODE]Promise((resolve, reject) => {[/ICODE]

[ICODE]  [/ICODE][ICODE]resolve(decisionService.execute(corticonPayload));[/ICODE]


Updating Your Views in React Native

So we've seen how to call and handle the response from your Decision Service. But there is more than one way to update your React Native Application. I would like to finish off this post then with a quick section on a couple ways to update your views based on the results of your Decision Service.


You may decide that it is logical for some Components to maintain their own 'state' and the state can be used inside your view. State is handled by React Native and comes with setters and getters (setState and getState). Your React Native application will automatically re-render any Component whose state is modified via setState. That means in the responseHandler above, 'this.setState({numCars: cars.length})' would cause whichever Component you invoked the Decision Service in to re-render.


Props are passed into your component from a parent Component. They essentially allow data to filter down from the top level of the application. If multiple components need to be re-rendered based on your Decision Service, one way accomplish this is to call your Decision Service in a top level Component and use Props to pass down data.

Another interesting use of Props is to pass a function to the child that updates the parent's state. This can be useful if you want to call your Decision Service in a child Component, but need to update the parent's state. Simply pass a function to the child Component and call it wherever you handle the response from your Decision Service.

Wrapping Things Up

Integrating your Decision Service into a mobile application with React Native is really quite streamlined. Generating your payload, calling and handling the response, and updating your applications view—everything is done once in JavaScript, without the need to look into Java Android or Swift iOS programming languages. That along with the overall ease of use of React Native means that building your first React Native application and Decision Service could really just be a matter of a couple days!

Continue reading...
Not open for further replies.