Monday, June 27, 2022

Break for javascript debug in chrome when sending xhr/fetch request

It is helpful to check the server request and response in chrome for javascript code, particularly if you do not have the source code information available to set breakpoint in a particular lines.

For chrome, this is easy to do by opening the developer console, and then open source tab, on the right side panel, under the section title of "XHR/fetch Breakpoints", add a new break point item for "Any XHR or fetch". 

The breakpoints requests to input string to break on matched url. In order to break on any xhr or fetch requests, just set the input string as '.', note '*' does not work for matching all purpose.


Thursday, June 23, 2022

Closure for javascript

In MDN web doc , A closure in JavaScript is defined as:

A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). In other words, a closure gives you access to an outer function's scope from an inner function. In JavaScript, closures are created every time a function is created, at function creation time.

The definition is not very clear as the closure involves both parent function and inner functions. So it needs more explanation about the definition:


When a (parent) function is executed, the function body will have all the local variables set to some value for the function execution. This execution environment including all the local variables is called parent function's lexical environment. 

If any inner function is defined within the parent function body, then the parent function's lexical environment will provide the variables defined in parent function, but referred by the inner function. Those variables are called closure variables.

The closure is created when the parent function is executed, and for each execution of parent function, a new closure environment is created. This makes sense, as each execution will have different variable values inside the parent function. All the inner functions defined in the parent function body, and whenever they are called, they will share the same lexical environment, i.e. the local variable's latest values declared in the parent function. 

So a closure is created when every time the parent function is executed, it captures all the local variables used by that execution instance. 

Note the closure only keeps the latest values of all the local variables defined in the parent function, so it the parent function does a for loop to update a local variable, then the local variable will have the latest value after the for loop finished. If a inner function is called later, then the inner function can only see the latest value of the parent function's closure variables, certainly the inner function can also update the closure variable to be visible to other inner functions. 

Sunday, January 30, 2022

CSS flex usage note

Flex can be used to solve most ui layout requirements in regular business applications if each items need to have equal height. 

Flex consists of flex container and flex items, each of them supports different css styles. It is important to understand which css style works on flex container or flex items.

Flex container:

For any container html element, when setting the below css style to it, the element becomes a flex container, and any direct sub elements become flex items.

.myform {

  display: flex;

}

The flex container has the below css styles:

.myform {

  display: flex;

  flex-wrap: wrap;  //control whether wrap the elements when page shrinks

 justify-content: center; // control where to shall all flex item in flex container in main axis: center, flex-start, flex-end, space-around, space-between

align-items: stretch; // control how each flex item is aligned in cross axis direction: stretch, flex-start, flex-end, center and baseline

align-content: normal: //control how all flex items are align in flex container in cross axis direction, not used very often.

}


Flex elements

Any direct sub elements of flex container element can be styled by flex item css styles. The styles controls the element itself and its sibling elements' behavior. The styles include:

flex: define how the element will grow or shrink when the page width changes. It can be used to define how item grows and shrinks related to other elements. For example, a growing input text box with a button with default width can be defined as below

   input[type="text"] {

      flex: 1 0 auto

  }

  button[type="submit"] {

    flex: initial 0 initial

  }


Sample usage 1

A growing field and a fix width item, the growing field occupies all remaining line

  .search-form {
    display: flex;
    flex-wrap: wrap;
  }
  growingitem {
    flex: 1 0 auto
  }
 fixeditem {
    flex: initial 0 initial
  }


Sample usage 2

Two fields occupy left and right end of the line by setting justify-content: space-between

  .search-form {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
  }
  input[type="search"] {
    flex: 1 0 initial
  }
  button[type="submit"] {
    flex: 1 0 initial
  }

Expanding item to occupy all its container's space 
When setting the below display style to any item within a container, the item becomes a flex container, and by default, flex container will expend and stretch to all available space in container.  
display: flex

Thursday, January 27, 2022

Difference between React useCallback and useMemo

React useCallback and useMemo hooks look similar, and both of them take a callback function, and dependent array as parameters. But their returns different values to the callers.

useCallback hook returns a memorized callback function, if the dependencies are changed. So the type of the variable assigned by useCallback is a function object. The function object itself is memorized, so when rendering the parent react function component, the function object will not be created again and again as new function objects. The function object body will not be invoked until in the project someone calls the function.

useMemo hook returns a memorized object, so the type of the variable assigned by useMemo may be any type depends what is returned from the callback method body in useMemo's first parameter. If nothing is returned, then the variable assigned by useMemo hook is undefined. Different from useCallback hook, when assigning a variable by useMemo hook, the callback method of useMemo hook will be called immediately, no matter whether the variable is used or not by the application. 

Since both useMemo and useEffect will automatically execute their callback method when page loads or when dependency parameters change, so their functions look similar. But useMemo is executed during DOM rendering. while use Effect is executed after DOM rendering, for the time consuming operation such as remote network requests. 

In practice, it is important in many times, the cost of using useCallback and useMemo may be bigger than the benefit bringing by it, and requirement of setting the proper dependent array parameter may introduce new bugs to the logic, so they should be used with caution in the real project.

Set dependent array parameter in useCallback (and other react) hooks

React callback hook creates memorized callback function, the memorized callback function gets created once, but will be invoked later for many times. If the callback function uses any values returned by useState() hook, then those values must be included in the useCallback's dependent array parameter. The reason is when useCallback is created, it captures all the closure variables as a snapshot for future usage. After that, if some values are updated by calling set method of useState() hook, the updated values will be not reflected in the closure snapshot captured by useCallback hook when it was created, so when the callback hook method is called after its creating, it will still use the original out-of-date values it captured when it was created. 

So as a simple rule, when defining hooks with dependent parameters, always including all values controlled by useState() in its dependent parameter.

Friday, December 24, 2021

Guidewire Jutro DataTable Usage (ver 4.1.1)

Jutro DataTable component is a major UI element when creating jutro pages, DataTable includes build-in pagination, searching, editing and no-data function, understanding how to use and configure jutro DataTable with metadata.json5 is very important.

1. Data source

DataTable metadata json5 definition has a data property, which accepts an array of item. Datatable's column is based on the item's attribute name. If you need to implement your own customized filter function, you can create a function to filter the data first and then feed the filtered data to the Datatable' data property.


2. search/filter 

For Jutro datatable, search and filter means the same. 

ShowSearch property controls whether to show a search input textbox on top of the datatable. If showSearch is set to true, then you can also specify a string on "filterPlaceholder" property to set a placehold text on the search input field. 

By default, when a search text is changed by user, the search criteria will check all records' all columns to get the matched records. However, you can customize the search behavior by specify DataTable's onFilter property to a custom function, and this function will be called whenever user changes the input of search input textbox field. A sample code is shown below:

      {

        "id": "myDataTable",

        "type": "container",

        "component": "DataTable",

        "componentProps": {

          "noDataText": {

            "id": "datatable.nodatatext",

            "defaultMessage": "No data found ...."

          },

          "expandOnRowClick": false,

          "defaultPageSize": 10,

          "pageSizeOptions": [

            10

          ],

          "filterPlaceholder": "",

          "rowIdPath": "publicID",

          "showSearch": true,

          "filterPlaceholder":"Search name, state, or population",

          "headerMultiline": true,

          "onFilter": "filterRow"

        },

    const filterTable = (filterValue) => {

        const filterNumber = parseInt(filterValue, 0);

        return (row) => {

            return row.claimNumber === filterValue;

        };

    };

  const resolvers = {

        resolveCallbackMap: {

            filterRow: filterTable

        }

    };


3. pagination

Pagination is supported by DataTable as build-in feature. The related settings include:

defaultPageSize : 10

pageSizeOptions : [10, 25]

showPagination: true


4. handle row click

When user clicks on a row, a custom callback function can be set to onClickRow property to handle the click, the input parameter is the row clicked.

  {

        "id": "ClaimSummary",

        "type": "container",

        "component": "DataTable",

        "componentProps": {

          "onRowClick": "onClickRow",

          "selectOnRowClick": true

        },

    resolveCallbackMap: {

            filterRow: filterTable,

            onClickRow: onClickRow

    }

    const onClickRow = (row) => {

        console.log(row);

    };


5. defaultSorted

Set datatable's default column for sorting


6. columnsConfigurable

true or false. Decide whether to show the three-bar button on right side of search bar for configuring columns.


7. Table column

Columns in DataTable are defined as an array under datatable's content property. Each column object's component property specify the column type, for example, DisplayColumn. The column object has below properties

header: specifying the header text

path: specify which datatable date object's field is for this column.

sortable: whether to show and support sort on this column

renderCell: specify a callback method to render the cell, the callback function has parameter of row item and row index

Tuesday, December 7, 2021

Guidewire Jutro notes

1. How to get all available properties for a component

Just opening project's framework/packages/components/widgets/folder, and then open the specific component you want to check.


2. Component settings in metadata definition

For object's component settings in metadata json5 file, it will first try to match the jutro component with the same name. If no match found, then it will match the html build-in element. For example, 

"component": "button"

will map to jutro button component, instead of html button element. But

"component": "label"

will map to html label element.


3. Content setting

The jutro framework will do its best to put the content into the mapped html element, for example, button will show the content string as its text. div will just show the content between the open and close tag. 


4. Add custom page/component

To add a new custom page, first create the page component and metadata json5 file. 

Then import the component in app.js file and also add the component into componentMap object.

In app.routes.metadata.json5, add a new path to load the page component for the specific route url path.

Actually this is the same change when running the below generate page command:

jutro-cli generate page


5. Enable guidewiree jutro capability buildin page

In addition to import the page component into app.js and componentMap, as well as updating the app.routes.metadata.json5, you also need to update config.json5's capabilitiesConfig section to set the capability's value to true. Otherwise the page/component jsx file will not be loaded.


6. Dynamic update UI with override in renderContentFromMetadata

When defining UI content with Metadata json5 format, all the values are hardcoded in json5 files. In order to dynamically change the values (for example, set element visible property based on server side response), the jsx file can set override parameter in renderContentFromMetadata method. For example, the below code sets claim element's visible property based on the return value of isClaimVisible()

       Claim: {
            data: claimDataTable,
            visible: isClaimVisible(),
}
Note, the method will only be called once when the UI is rendered from metadata, once the rendering is finished, even if the function returns a different value, it will not be called again automatically.
In order to be sure UI will reflect the underling data change, in the data change handler function, it should call useState() method to notify react to refresh the UI, so the metadata will be evaluated again. 
Basically, values set in override parameter is same as other react component properties, and they are read only when passed to child component for initialization. 

7. Difference between to and href for Link component
When href attribute is set for Link component, it will cause to reload the page on that url, which will download the full index.html and js files.
When to attribute is set for Link component, it will stay in the current html page, and only reload the component based on app.js router configuration. So it is much fast and user friendly.