< Previous | Next >

Lesson 5: Add code to the mortgage calculator handler

Add functions to the handler that you created in the previous lesson.

In this lesson, you work directly with EGL source code, starting with an EGL library that you write. A library can contain constants, variables, and functions, any of which can be accessed by the different units of logic in your application. An important characteristic of a library is that changes to a variable are available to any unit of logic that accesses the library. However, the focus in this tutorial is on functions, which you place in a library to avoid having to maintain the same, widely used logic in multiple places.

To handle some commonplace issues, you can use the EGL Model View Controller (MVC) framework, which is provided by the com.ibm.egl.rui project. Although the initials "MVC" typically describe the different components of an enterprise application, the MVC framework in Rich UI concerns only the components of a user interface. Here, the model is a variable or record field, the view is a widget, and the controller is a declaration that oversees the transfer of data between the model and view. That transfer of data is sometimes automatic and is sometimes a response to a function invocation, as shown later.

The drag-and-drop actions of the previous lesson added not only controller declarations, but a form manager, which is a declaration that lets you treat other declarations as components of a single form. A form manager includes a set of form fields, each of which can include a label, a controller, and an error field.

Create an EGL library

Create an EGL library to hold a function that provides U.S. currency formatting for a MONEY variable. A more complex version might allow for local currency symbols and separators and different input types. However, for this tutorial, a simple version will suffice.
  1. Select the MortgageUIProject in Project Explorer.
    MortgageUIProject is selected.
  2. Click the New EGL Source File button.
    The New EGL Source File button is the second in a group of four.
  3. In the New EGL part window, specify the package as follows:
    libraries
  4. Name the file as follows:
    MortgageLib
  5. Click Finish. The new source file opens in the EGL editor.
  6. Remove the comment from the file and add the following code:
    library MortgageLib 
       function formatMoney(amount STRING in) returns(STRING)
          len int = strlib.characterLen(amount);
          index int = len - 6; // 2 dec places + decimal + 3 chars before separator
          while(index > 0)
             amount = amount[1 : index] :: "," :: amount[index + 1 : len];
             index -= 3;
             len += 1;
          end
          return("$" :: amount);
       end
    end

    As shown, you specify the library name and embed a new function, formatMoney(), which adds commas and a dollar sign to an input string. The assumption here is that the input field contains a money value with two decimal places.

  7. Save the file. The library is automatically generated once the file is saved.
The MortgageLib library is now ready to use.

Change the code in the handler

Before you add new functions, you must make a few minor changes:
  1. Click the Source tab for MortgageCalculatorHandler.
  2. Set default values for the Loan amount and Interest fields. Go to the line where the inputRec record is declared and add the two assignments to the declaration, as shown here:
    inputRec MortgageCalculationResult 
       {term = 30, loanAmount=180000, interestRate = 5.2};
    Save the file and click the Preview tab. The interface now shows the default values, including the value that you specified in the previous lesson, for the term field:
    The interface now shows a loan amount and interest rate.
  3. On the first line of the handler, before the declaration of the ui widget, declare a variable that the code uses to access the dedicated service:
    mortService MortgageCalculationService{@dedicatedService};
    The mortService declaration comes before the ui GridLayout declaration.
  4. Hover your cursor over either the red x or the red underline to learn that the cause of the error is as follows: “The type MortgageCalculationService cannot be resolved.” The error might be puzzling, given that you earlier set the EGL build path for the project in which you are working so that the project can access the one that contains the service. The problem here is that the source file is not importing the Service part.
  5. To remove the error, type the following import statement after the other import statements in the file:
    import services.MortgageCalculationService;
    After a few seconds, the error marks are removed even though you did not save the file.
  6. In many cases, the development environment can insert a missing import statement for you. To see this convenience in action, remove the import statement that you just typed. When you see the error marks return, type Ctrl+Shift+O to reinsert the statement.
  7. Save the file.

Complete the inputRec_form_Submit function

EGL created a stub inputRec_form_Submit function. The intent is for the function to validate all the fields on the form and to “commit” them. The commit is part of the MVC implementation and means that the inputRec record is updated with the values in the widgets.

You will add code to call two other functions. The first function makes the processImage image visible and in this way tells the user that the application is working. The second function calls the service to calculate the mortgage payment.

To complete the inputRec_form_Submit function, update the if statement so that it reads as follows:
if(inputRec_form.isValid())
   inputRec_form.commit();
   showProcessImage();
   calculateMortgage();
else
   errorLabel.text = "Input form validation failed.";
end
Do not worry about the code format; a later section handles the issue. Also, the next sections remove the error marks that are shown here:
The complete inputRec_form_Submit() function call.

Add the showProcessImage function

You need the showProcessImage function to make the processImage image visible. To code the function in the Rich UI editor, add the following lines before the final end statement in the handler:
function showProcessImage()
   processImage.visible = yes;
end
Note: The visible property is part of any Image widget. You changed the initial value of this property in the previous lesson, when you cleared the visible check box for the processImage image.

Add the hideProcessImage function

You need the hideProcessImage function to hide the image when necessary. Add the following lines after the showProcessImage function:
function hideProcessImage()
   processImage.visible = no;
end

Add the calculateMortgage function

The calculateMortgage function calls a service to do a mortgage calculation based on the values displayed in the UI. To code the function in the Rich UI editor, add the following lines after the hideProcessImage function and ignore the error marks:
function calculateMortgage()
   call mortService.amortize(inputRec) 
      returning to displayResults 
      onException handleException;
end	
Note:
  1. The call statement in Rich UI is a variation used only to access services. The runtime communication in this case is asynchronous, which means that the user can continue to interact with the handler while the service is responding.
  2. A service requester often passes a record to the service being accessed. In this tutorial, the handler passes the global inputRec variable and receives, in the same record, the value returned from the service.

Add the displayResults function

The displayResults function is a callback function, which runs immediately after the service successfully returns business data to the Rich UI handler. To code the function, add the following lines after the calculateMortgage function:
function displayResults(retResult MortgageCalculationResult in)
   paymentLabel.text = MortgageLib.formatMoney(retResult.monthlyPayment as STRING);
   inputRec_form.publish();
   hideProcessImage();
end
Note:
  • You use the formatMoney function from your new EGL Library part to add commas and a dollar sign to the payment amount. Because you created the paymentLabel variable without involving the MVC framework, you must handle the formatting yourself.
  • As noted earlier, a form manager includes form fields that in turn can include controllers and other declarations. The publish function is available in any form manager and invokes the controller-specific publish functions, one after the next, to do as follows:
    1. Retrieve the data from the variable that serves as the controller model.
    2. Format that data.
    3. Write the formatted data to the widget that serves as the controller view.

    Given that sequence of events, the form-level publish function is often invoked as it is here: in a callback function that receives data from a service.

Write the exception handler

If the service invocation results in an error, the usual callback function is not invoked. However, if you arranged for the use of an exception handler, as in this case, that function is invoked.

Do as follows:

  1. After the displayResults function, add the following code:
    	// catch-all exception handler
    	private function handleException(ae AnyException in)
    		errorLabel.text = "Error calling service: " + ae.message;
    	end
    Functions with the private modifier can only be called by the EGL part where the function resides; in this case, by the embedding handler. The function places text in the errorLabel widget that you created in the previous lesson.
  2. Update the calculateMortgage function immediately before the call statement, as follows:
    errorLabel.text = "";
    In this way, you clear the errorLabel field before you invoke the service that does a mortgage calculation. If you do not add that code, an error such as the temporary loss of service connection will display an error message, even after the service is invoked successfully.
  3. Right-click an empty space in the editor. Click Organize imports. EGL adds import statements for all the undefined symbols that it can.
  4. Save the file. If you see errors in your source file, compare your code to the file contents in Finished code for MortgageCalculatorHandler.egl after Lesson 5.
  5. After you resolve any errors, reformat your input by pressing Ctrl+Shift+F and save the file again.

Test the calculator

You are now ready to test the calculator.

  1. Change to Preview view by clicking the Preview tab at the bottom of the editor. You can fully test your application in the Preview view, including the user interface and services. You can do your testing whether the services are deployed on a server or are available only as EGL source code. EGL displays the default values that you entered when you created the handler.
  2. Click Calculate. EGL displays the monthly payment.
    The monthly payment amount appears in the Payment field.
  3. Type a letter in the first field. As is true of several EGL Dojo widgets, a red mark is displayed as soon as an error occurs, and an error message is displayed in an adjacent tooltip.
    The monthly payment amount appears in the Payment field.

    When the widget loses focus, the tooltip is hidden, and when the widget regains focus, the tooltip is shown.

  4. Change the values for any of the three fields and click Calculate again. The Payment field changes accordingly.

Lesson checkpoint

You learned how to complete the following tasks:
  • Work in the Rich UI editor Source tab
  • Create an EGL Library part for reusable functions
  • Use EGL Model-View-Controller framework
  • Call an EGL Service from a function
  • Catch and handle errors

In the next lesson, you create a pie chart to compare the total principal to the total interest in a given calculation.

< Previous | Next >

Feedback