Skip to main contentMAF Configuration Practices

FAQ

Replace or add logic into existing method

Replacing or adding logic to a particular controller’s method is a common request however there are differences and best practices to do so. When a controller is bound to the application, page, or datasource, the controller class can handle any events that are dispatched. If the controller has a function that matches the event name, it will be invoked to handle the event.

By replacing a method you can ensure the sequence of steps to be executed. The idea behind this practice is to use the initialize event of the object where the controller is associated with, store the method out-of-the-box in a variable so you can opt for using it later, and re-assign the reference of the old method to a new one. You can find more details and sample here.

Adding new steps to a method requires the creation of method with the same name at AppCustomizations.js file. The sequence the methods to be executed cannot be enforced, all methods with the same name are subscribed to that event dispatched and the order is not guaranteed by the platform mechanisms. You can find an example here.

Handle events with no alias

Most of events from component lifecycle have alias. For instance, originally, onBeforeLoadData event in fact is emit as before-load-data but for sake of simplicity and language pattern. Usually events have its alias with “on” prefixed and gets converted from dash case (kebab Case) into camel case. However, a couple events does not have a alias(for now), this is the case of events like:

  • before-invoke-action
  • after-invoke-action
  • field-warning

In those cases, the raw name can be used to capture those events, but due to dash chars the name should be wrapped in quotes.

'field-warning' = ({item, field, warning}) => {
if (warning) {
// Do this and that
}
}

Alternatively, you may bind event listeners during the initialization of the application or page. It is equally important to ensure that these listeners are properly removed once they are no longer needed.

pageResumed(page, application) {
ds.on('field-warning', this.fieldWarningHandler)
}
pagePaused(page, application) {
ds.off('field-warning', this.fieldWarningHandler)
}

How to filter with datasource?

There are a few ways to fetch the right amount of data to the appropriate context.

  • QBE filter (declaration or API)
  • Where clause
  • Saved Query
  • Mobile QBE Filter

The last one is exclusive for mobile apps searching against data previously loaded. Basically mobile-qbe-filter is a qbe filter used by the apps when running in the mobile container. It’s only used when fetching data from the local db (on the device) and not used when fetching data from maximo/server. Mobile only supports mobile-qbe-filter on the “top most” object.

Considerations about translating all characteristics of a where clause into Mobile-QBE-Filter:

  • Nested properties does not work in mobile, instead an alias should be used and referenced in the QBE filter.
  • Variables like SYSDAY are interpreted only in server, so avoid using it.

Saved query should be used to be the less restrictive filter. If there is additional filter criteria, then you would add to the maximo-datasource a where (for web) and mobile-qbe-filter (for mobile) to reduce the dataset. Lookup datasources for Maximo Mobile need to use the same saved query so it’s important that you implement the filter with where & mobile-qbe-filter.

How to make a datasource field available in sort list

In order to make one of those attributes listed in schema part of sort list just set the “sort” attribute of the field to “true” or remove sort attribute and value all together.

<attribute name="location.description--locationdesc" searchable="true" id="d_m_3"/>

Why should I avoid multiselect component?

Even though multiselect component seems to be more appropriate to address a simple selection in input field, this component is not recommended for that task. A few bugs were found in the library that uses it and this might be addressed in the next releases (v9.2). Instead, we suggest using either data list or lookup. Take a look at one of the cases using lookup, Create Priority Lookup in Techmobile for instance.

Should I duplicate an object structure to work with a particular app

Duplicating object structure(OS) seems to isolate the object usage but this practice is discouraged. Due to mobile architecture, all data coming from object structures sharing the same root object get merged to supply data in a disconnected mode and this operation can can exclude exclusive attributes from a duplicate object structure. It is recommended to reuse the same OS to avoid data conflict and apply logic in the app to use only the necessary data to be displayed.

How do I know if my app has any configuration/customization

Often, as part of the case triage process, it is necessary to determine whether a customization or configuration is in place before beginning to investigate the issue.

In the context of MAF, there is a consolidated dashboard that displays the installed applications and their current application revision. Up to MAF version 9.1, the dashboard only shows active versions.

The revision also serves as an indicator of configurations added to installed applications. Maximo Manage applications are stored in the MAFAPPDATA table, which includes the application ID, binary file, version, revision, checksum, as well as information about who deployed it and when. The version is extracted from the build.json file within the application binary, while the revision and checksum are calculated when the binary is uploaded. Each time a new application record is inserted—whether via UpdateDB, maxdev-cli upload-app, or the Configuration Application (through a publish)—a new revision is created and set to ACTIVE.

To retrieve revisions directly from the database, use the following SQL statement:

SELECT m.APPID, m.DEPLOYBY, m.DEPLOYDATETIME, m.STATUS, m.VERSION, m.REVISION, m.ISMOBILE FROM MAFAPPDATA AS m WHERE m.STATUS = 'ACTIVE';

For customization in CSS(Cascading Style Sheets is code that defines the visual appearance of the user interface), on the Suite administration page, from the side navigation menu, click Configurations and then click User interface customization. On the CSS customization tab, check toggle button that enables CSS customization.

I cannot push changes of my custom object children

All modifications to records—whether initialized or retrieved from a datasource—are automatically tracked, including those originating from child datasources. Persisting these changes is handled by the save() API of the corresponding datasource.

  • BMXAA10013E - Invalid URI for updating resource. The URI needs to end with the resource REST id. If the operation fails due to misconfiguration, verify that the parent-child datasource relationship is properly established within the Database Object and reflected in the source code of the primary Object Structure.

  • BMXAA3761E - The event has failed. Ensure that the event is registered correctly. Cannot invoke “com.ibm.tivoli.maximo.notification.OSEventInfo.isFireEvent(psdi.mbo.MboRemote)” because “eventInfo” is null Events from notification app might be restricting operations. Access the notification app and check records related to the Object Structure, delete them and retry the operation..

How to determine problems after upgrade?

After a version upgrade the customization should be re-tested and here are some steps to triage a customization problem after version upgrade.

  • Check if the ID references still exist, specially states and datasources declared in XML.
  • Check MAS and MAF versions match using compatibility matrix