Using javascript expression and saving to Database


How do i pass the data from javascript expression to the Database? I have been able to do the calculation and its good now , so i want to use the expression and send into the database so i can call the information up later and use it for the approval view.

the Javascript i used looks like this :

`var resultCalculate = Number($data.perdiemInput) * Number($data.noOfNightsInput);
return resultCalculate;`

This calculates the number of Nights and the per diem and then its bound to the input feild like this


Now i want to have these feilds sent to the database and i have ransacked online and I have not seen any useful tutorial or information of some sort. I really need help here.


Submitted by antoine.mottier on Tue, 05/07/2019 - 08:14

Here is a description of the data flow from the user web browser to the business database schema managed by Bonita Business Data Management (BDM) feature:

1. When user input some data in a form widget the value is saved in the form variable (i.e. a JavaScript object) associated with the `Value` property of the widget.
1. The submit button of the form is configured (`Action` property of the widget button) to either start a new process instance or submit a task. When clicked it will call the Bonita Engine API giving the order to start the process or execute the task and, in the same call, data entered by the user are sent. Data to send are defined by the `Data sent on click` property of the widget button. Value of `Data sent on click` is usually a form variable. It can be directly a variable associated with one or several form widgets (as variable are JavaScript objects they can have multiple attributes and each attribute value can be updated by a different widget) or a JavaScript variable that is used to aggregate together values of different form variables. The JavaScript variable is convert into some JSON to be sent in the HTTP request to Bonita Engine API.
1. Data received by the Engine will be matched against the process or step contract. They should exactly match. For example the following JSON: {"contractInput": {"attributeA": 123, "attributeB": "test"}} should be used with a contract input named "contractInput" declared with a type "complex". This "complex" contract input must have two attributes: one named "attributeA" of type integer (or long, or float...) and one named " attribute B of type "text".
1. Next the contract information can be used to set the default value of a business variable declared in the process definition. Usually the first step is to declare the business variable and then generate the form or step contract out of it: this will automatically generate the Groovy script that create the new business variable object based on contract inputs. Then you usually generate a first form based on the contract definition.
1. Setting the default value of a business variable actually automatically trigger the insertion of the data in the database. Note that contract information can also be used in operations on task (an operation can be used to initialize a business variable or update an existing one), as connectors input data...

I hope this will help you. Also I recommend when testing that to take a look at the "network" tab of the developer tools available in the web browser (F12 key shortcut) when you submit the form (you should the HTTP call with the form data), also take a look at the Engine log file from Studio help menu and finally take a look at the test business database (h2) available from the "development" menu in the Studio.

Submitted by raysoniali on Tue, 05/07/2019 - 10:12

I created 3 variables which i used to do calculations

i called one numberOfNights = Name , Value = numberOfNights type = String, the second one perdiem = Name , Value = perdiem type = String and the last one
is a javascript expression i used for some calculations

Now i used some Javascript function like this :

var CalculateAmount = Number($data.perdiem) * Number($data.numberOfNights);
return CalculateAmount

when i created another variable of Type Javascript Expression with name PerdiemCalculateDays , now i save.

Now i have this as my FormInput which is suppose to hold the Data

  "travelRequestInput" : {
    "departureDate" : null,
    "fullname" : "",
    "hotelNeeded" : false,
    "origin" : "",
    "destination" : "",
    "reason" : "",
    "supervisorName" : "",
    "supervisorEmail" : "",

And formOutput which is supposed to save the Data inside the Database but instead i get empty columns inside the Database with 0.00 every whre like this


Asides that other things seem to work pretty good , the connectors and workflows are fine.

Submitted by antoine.mottier on Tue, 05/07/2019 - 10:40

Can you export your process, forms and BDM from the Studio as a .bos file and share it using Google Drive, Dropbox...?

Submitted by raysoniali on Tue, 05/07/2019 - 10:43
Submitted by raysoniali on Tue, 05/07/2019 - 13:24

No word from anyone. I am really having a very tough time here. what am i apparently missing ?

1 answer

This one is the BEST answer!

I will try to explain what I did to find out the issue in your application and how to solve it.

So first I open your process and took a look at your process instantiation contract. I can find that a complex contract input is defined (named "travelRequestInput") and this complex input has three attributes that seems related to the data you report not being stored in the database: numberOfNights, perdiem and totalAmount.

Next I checked the business variable. One business variable is declared in the process (named "travelRequest") of type "TravelRequest". The default of this business variable is set mostly (except "userId" and "status") using the contract input including numberOfNights, perdiem and totalAmount attributes.

I also took a look at BDM definition to make sure that attributes names are correct (i.e. match what is used in the default value) and what data type are used.

So far everything seems correct.

So next step is to take a look at the form. Instead of digging in the form I just try to run the process and submit the instantiation form. Submitting the form trigger a REST API call (i.e. an HTTP request) from the user web browser to the Bonita server. Using the web developer tools of the web browser (usually open with F12 key shortcut) we can find in the "network" tab the request being sent asking the engine to create a new instance of the process and providing data as part of the request payload (using JavaScript Object Notation - JSON).

So I submit the process an in the POST HTTP request to http://localhost:45789/bonita/portal/resource/process/LocalTravel%20Request/1.0/API/bpm/process/7763908911897244584/instantiation I get the following JSON:


This JSON represent an object with 3 attributes:

  • travelRequestInput, type: object, value:


  • numberOfNights, type: number, value: 3

  • perdiem, type: number, value: 5

We can see that the travelRequestInput object has itself three attributes: numberOfNights, perdiem and totalAmount all with a value of 0.
So here we have a first part of the issue. We have duplication for numberOfNights and perdiem attributes. Moreover the actual value is not in the JSON structure that match the instantiation contract defined in the process but in some extra attributes that will be ignore by Bonita.

Now let's edit the form in the UI Designer. The property "Data sent on click" of the submit button define which JavaScript variable (object) will be used to create the JSON value sent when the button is clicked.
You defined a variable named "formOutput" associated with the submit button. This variable is initialize with the following JavaScript:

return {
    'travelRequestInput': $data.formInput.travelRequestInput,
    'numberOfNights': $data.numberOfNights,
    'perdiem': $data.perdiem,
    'totalAmount': $data.PerdiemCalculateDays.value

So here we can already fix issue for numberOfNights and perdiem and do a first part of the work for totalAmount: just remove them from the script and only keep:

return {
    'travelRequestInput': $data.formInput.travelRequestInput

And update the widgets for numberOfNights and perdiem to update formInput.travelRequestInput.numberOfNights and formInput.travelRequestInput.perdiem (instead of numberOfNights and perdiem variables, and delete those useless variables).

If you run the process at this stage (after saving the form) you should have correct data for numberOfNights and perdiem. Now let's fix the totalAmount.

Add the following statement in the "PerdiemCalculateDays" variable JavaScript initialization code (before the return): $data.formInput.travelRequestInput.totalAmount = CalculateAmount
and also update the references to numberOfNights and perdiem:

var CalculateAmount = Number($data.formInput.travelRequestInput.perdiem) * Number($data.formInput.travelRequestInput.numberOfNights);

And update the widget "Total amount" to use formInput.travelRequestInput.totalAmount for the value.

And that should be it!


Submitted by raysoniali on Wed, 05/08/2019 - 09:12

Thank you so Much for the Kind and very detailed Explanation, It works fine as expected now. You sure made my day. Merci Beacoup!