Precision Healthcare Solutions
CLINICAL OFFICE MPAGE SUITE DEVELOPER REPORTS DESIGNER shopping_cart mail
SALES CONTACT US
Getting StartedCerner SetupDeveloper PC SetupGitHub Project TemplatesFull Page DeploymentWorkflow ComponentsComponents & DirectivesButtonConfirm DialogDate Range PickerDrop-DownIconInputLogOptional TitlePatient SearchRadio ButtonsRemaining Screen SpaceScroll BarSelectTabbed MenuTableTreeModels & ServicesAddressAllergyCerner FunctionsCode ValueConfigCustomDiagnosisDialogEncounterMPageOrganizationPersonPersonnelPhoneProblemReferenceUtility

MPage Service

Overview

The MPageService service contains all the communications logic built into MPage Developer. All other services (e.g. PersonService, CustomService, etc.) make use of the MPageService to communicate with CCL, post log messages, and more.

Import

The MPageService needs to be imported into any component or service that makes direct calls to the MPageService. Other MPage Developer services such as PersonService contain a reference to the MPageService, meaning that if you are strictly using another service and its methods, you do not need to import MPageService directly into your components.

import {Component, inject, OnInit, ...etc...} from '@angular/core';
import {MPageService} from '@clinicaloffice/mpage-developer';

Object Assignment

Both the full page and component MPage templates have MPageService setup in the project app.ts file. The MPageService is initialized with two instances (queues), the log enabled, 'CHART' mode, and the GUI login set to false. Each of these options is customizable with explanations listed below in the Methods portion of the documentation.

To use the MPageService in your application, you must inject it into your component or service with the inject function.

The following code illustrates a standalone component in the app.ts file that injects the MPageService to an object called MPage. The MPage object is initialized in the ngOnInit() method by assign values with the setMaxInstances function. Finally, the defaultDateFormats value is assigned the CUSTOM_DATE_FORMATS constant.

@Component({
    selector: 'app-root',
    imports: [MpageLogComponent],
    templateUrl: './app.html',
    standalone: true
})
export class App implements OnInit {
    public MPage = inject(MPageService);

    ngOnInit() {
        this.MPage.setMaxInstances(2, true, 'CHART', false);
        this.MPage.defaultDateFormats = CUSTOM_DATE_FORMATS;
  }
}

CUSTOM_DATE_FORMATS

The CUSTOM_DATE_FORMATS constant is assigned in your app.config.ts file. It contains various date related formats that you can use in your MPages. The MPage Table component uses these date formats when displaying dates and date/time values in the table output.

Available Public Variables/Objects

NameTypeDescription
alternateReplacerbooleanDetermins if alternate JSON replacer should be used.
personIdnumberPerson ID of patient in context in CHART mode. 0 in ORGANIZATION mode.
encntrIdnumberEncounter ID of patient in context in CHART mode. 0 in ORGANIZATION mode.
nameFullFormattedstringPatient Name.
prsnlIdnumberId value from the PRSNL table for the current user.
prsnlNamestringName of the current user.
usernamestringUsername of the current user.
positionstringPosition of the current user.
positionCdnumberCode value of the position of the current user.
physicianIndbooleanIndicates if the current user is a physician.
domainstringCurrent logged in Cerner domain name.
nodestringCurrent Cerner node used for CCL requests.

Other public variables do exist in the MPage service, however, they are for use by internal MPage Developer services and components. Using these other values is not supported, and you do so at your own risk.

Methods

activeTaskCount(): number

Returns a count of the number of CCL jobs currently running plus the number of jobs queued to run.

assignCredentials( userName: string, password: string, domain: string ): void

Used by the internal login component to assign user credentials. It could also be used to send hard-coded credentials to web facing MPages for automated views such as surgery wait-list MPages.

If using, call this method before calling the setMaxInstances method. While it is never a good idea to store login credentials in the open, under very controlled circumstances, the ability to auto-login to an MPage can be very helpful.

When assigning credentials with the assignCredentials method, you should pass the domain value from MPage.domain as the value does get overwritten during runtime. Ensure that the only domain name in your config.json file is the domain you wish to have your MPage login to. Finally, you must also set the triggerLogin parameter to true in the setMaxInstances call.

The example below demonstrates how this can be accomplished using credentials stored in the config.json file included with your application. When run from a browser, the MPage will automatically log in with the "kiosk" user.

app.ts

export class App implements OnInit {
  public MPage = inject(MPageService);
  public configService = inject(ConfigService);

  ngOnInit() {
    const credentials = this.configService.config.credentials;
    this.MPage.assignCredentials(credentials.username, credentials.password, this.MPage.domain);

    this.MPage.setMaxInstances(2, true, 'CHART', true);
    this.MPage.defaultDateFormats = CUSTOM_DATE_FORMATS;
  }
}

config.json

{
    "contextRoot": "http://sub_domain.host_name.com/discern/domain/mpages/reports",
    "domain":["b1234"],
    "credentials": {
        "username": "kiosk",
        "password": "kiosk"
    }
}
config(): any

Returns a basic config object identifying the mode ('CHART' or 'ORGANIZER') and a hexMode value indicating if the MPage is being run from PowerChart or not.

contextRoot( value: string )

Allows you the ability to explicitly assign the location of Discern Web Services in your MPage. Typically, this is set up through the config.json file paired with the config service as described in the GitHub Templates documentation, however, the method is exposed here if you need it.

MPage.contextRoot = 'http://sub_domain.host_name.com/discern/domain/mpages/reports';
emptyPatientSource( ): IPatientSource

This get method returns an IPatientSource object with the contents of { personId: 0, encntrId: 0 }.

executeCCL( payload: any, instance: number = 0, callback: any = undefined, cclDebug: boolean = false ): void

The executeCCL method is the primary method called by data services to execute CCL scripts. The payload parameter needs to contain a properly formatted JavaScript object with instructions on what data is to be collected by CCL. The instance parameter is used to specify the CCL instance you wish to run. If you pass a value of 0 to the instance parameter, the next available instance will be used.

The optional callback parameter allows assigning a method to be executed once your executeCCL script has been completed.

Callback Examples

Example 1:
----------
this.MPage.executeCCL(payload, 0, () => { this.MPage.putLog('I will run as soon as data comes back'); });

Example 2:
----------
this.MPage.executeCCL(payload, 0, () => { this.runAfterExecute() });

protected runAfterExecute(): void {
    this.MPage.putLog('The runAfterExecuteMethod is called as soon as data comes back.');
}

The cclDebug parameter is only used by the MPage Log component to assign log files and should be ignored in your code.

Information on valid payload values are found later in this document.

formatDate( JSDate: Date includeTime: boolean ): string

Formats a JavaScript date to dateLabel or dateTimeLabel defined in your CUSTOM_DATE_FORMATS constant.

CUSTOM_DATE_FORMATS = {
  parse: {
    dateInput: ['dd-MMM-yyyy'],
  },
  display: {
    dateInput: 'dd-MMM-yyyy',
    dateLabel: 'dd-MMM-yyyy',
    dateTimeLabel: 'dd-MMM-yyyy HH:mm',
    locale: 'en-US',
    monthYearLabel: 'MMM yyyy',
    dateA11yLabel: 'LL',
    monthYearA11yLabel: 'MMMM yyyy',
  }
}
fromJSDate( JSDate: Date, includeTime: boolean = true ): string

Convert a JavaScript Date object into an HTML input compatible date (yyyy-MM-dd) or datetime-local (yyyy-MM-ddTHH:mm) string.

inPowerChart(): boolean

Determine if code is running from the Discern output viewer. Will return true in PowerChart and DA2/Reporting Portal.

load( payload: any overridePayload: any patientSource: IPatientSource[] callback: any additionalProperties: any = undefined ): void

The load method is an internal method for calling the executeCCL method with additional properties from the internal MPage Developer services. It is documented here for completeness but should not be used directly in your MPages, and instead you should be using executeCCL directly to load data from Cerner.

notifyUser( message: string, delay: number, position: string, width: string, color: string )

The notifyUser function will present the user with a notification pop-up message that can be dismissed when clicked on by the user. The message can be any string of text you would like displayed. Delay is in seconds and a value of 0 indicates that no delay should be used. If a delay value has been set, the notification will hide after the delay period has ended.

Valid position values include 'top', 'bottom', and 'center' and the width can be any valid CSS width value (e.g. '24px', '10em', etc.).

Any defined color scheme in your CSS file can be used for the color value (e.g. primary, accent, warn).

this.MPage.notifyUser('You have been notified', 0, 'bottom', '20em', 'primary');
putLog( text: string, type: string = 'info', processId: number = -1, statusText: string = '' ):

The putLog method assigns a text message and associated type to the MPage log component. Valid values for type are 'info', 'payload', 'error', and 'debug'. The processId and statusText parameters are internal use values and can safely be ignored.

ping(callback: any = undefined):

The ping method makes a simple call to CCL, which populates the internal MPage variables (e.g. personId, encntrId, etc.). The ping method is called as the last step in setMaxInstances.

You will most likely never use this function, however, you can use the ping method to make a dummy CCL call and execute code in a custom assigned callback.

serviceReady(): boolean

This get method returns a boolean value indicating if the initial ping call has completed and access to Cerner has been verified.

setMaxInstances( maxInstances: number, enableLog: boolean = false, mode: string = 'CHART', triggerLogin: boolean = false ): void

Initializes the number of XMLCclRequest objects needed for the application. Execution is required before any Clinical Office: MPage Developer functionality can run. This method can only be run once.

If the MPage is run outside Cerner in a web browser, XMLHttpRequest calls to a single queue are made instead.

MPageService offers advanced queuing capabilities giving you the ability to specify several work queues to make CCL requests through. Requests are taken in order with the next available queue. The maxInstances property allows you to assign the number of queues you wish to enable in your MPage. The recommended setting is between 2 and 4.

The enableLog property allows population of data into the MPage Log component. If set to false, the MPage Log component will not be available, regardless of if you have added it to your component.

You can assign a mode to your MPage to determine if patient context is included or not. MPages running on an open patient chart should have this mode property set to 'CHART', while all other use cases should be assigned the value of 'ORGANIZER'.

The triggerLogin property is relevant only when an MPage is run outside Cerner in a web browser through Discern Web Services. If set to false, the user is prompted with a standard Windows login which asks for the username and password. The username must include the Cerner username, @ symbol, and domain name to function. Setting the triggerLogin property to true will display a GUI login screen that includes a drop-down menu for the domain name. The names of the domains are assigned in the Config service.

toJSDate( stringDate: string, includeTime: boolean = true ): Date | string

Convert an HTML input date (yyyy-MM-dd) or datetime-local (yyyy-MM-ddTHH:mm) value into a JavaScript Date object.

userLoginDomain(): string

This get method returns the current domain name

Payload

The payload executed by the executeCCL method of the mPageService is read by CCL to determine which patients/encounters are to be used as well as which CCL scripts are to be executed.

The minimum requirement for your payload object is to have a root object called payload. While it won't actually do anything, the following is a completely valid payload to be sent to CCL.

{
  payload: { }
}

Choosing Patients/Visits

If you do not include a patientSource in your payload and are running in CHART mode, a default patientSource will be generated for the current encounter.

You can specify one or more patients and/or visits in your payload with the patientSource element. You can use a combination of personId and/or encntrId values. If you specify an encntrId but leave personId set to 0 and call a CCL script that requires personId, it will automatically be calculated for you. Providing a personId with no matching encntrId will not default encntrId's for your CCL as the volume of encounters could be very high.

{
  payload: {
    patientSource: [
      {personId: 123456, encntrId: 0},
      {personId: 0, encntrId: 789012},
      {personId: 234567, encntrId: 911233};
    ]
  }
}

Executing CCL Scripts

Each CCL script developed for Clinical Office:MPage Edition has a unique payload tag. For example, the PersonService uses a payload tag called "person". The documentation for each data service includes a tab indicating all the payload tags used by that service. Each data service offers a method for calling the correct payload.

Sometimes, however, you may wish to call the executeCCL script manually with your own payload. This is possible, and any data services you have running in your script will automatically reflect any new data loaded through a manual executeCCL call. It is also possible to call many CCL scripts at the same time through the same CCL instance. For example, you may have a custom CCL being called which collects a list of qualifying visits. Instead of writing the CCL code to pull patient demographic or encounter specific data, you can simply chain the payload values together.

In the example below, a custom script called 1_cancer_patients is called followed by the code to collect the person records and encounter records. The custom script only needs to populate the record structure in CCL called PATIENT_SOURCE with the ENCNTR_ID's of the patients qualified. No other information is needed in the CCL to retrieve everything needed for the MPage.

{
  payload: {
    clearPatientSource: true,
    customScript: {
      script: [{name: '1_cancer_patients', run: 'pre', id: 'cancerpat', parameters: {} }]
    },
    person: {
      patient: true,
      prsnlReltn: true
    }
    encounter: {
      aliases: true,
      prsnlReltn: true
    }
  }
}

Clear Patient Source

The last example introduced a payload option called clearPatientSource. If set to true, clearPatientSource will remove all person and encounter information from the incoming record structure. It is then up to you to populate the patient_source record structure in CCL before any Clinical Office data services are called.

patient_source (
   1 visits[*]
      2 person_id = f8
      2 encntr_id = f8
   1 patients[*]
      2 person_id = f8
)

Default Payload Tags

Each data service offers default payload values that you can override in your app.component.ts script after setting your mPageService max instances. Each default payload tag is documented with the service it is used in.

For example, the PersonService offers three default payload objects that you can easily override. The defaults are called "PERSON_MIN", "PERSON_PATIENT" and "PERSON_PRSNL". They are stored in a Map contained in the MPage service.

The "PERSON_MIN" payload tag simply indicates that along with the data from the PERSON table, it is only going to collect the PERSON_ALIAS values. During the design of your MPage, you may also want to always return code values every time "PERSON_MIN" is executed in the PersonService. You would change it by adding the following line to your app.component.ts script in the ngOnInit() method right after your call to the setMaxInstances method.

this.mpage.defaultPayload.set('PERSON_MIN',
  person: {
    includeCodeValues: true,
    aliases: true
  }
);

Default payloads can also be used in your custom payloads. In our Cancer patients example shown above, we have now decided to load as much information about the patient as we can. To do this, we are going to use the "PERSON_PATIENT" payload which includes code values, aliases, person patient, names, person info, personnel relationships, person relationships and organization relationships.

We could have typed all the parameters for these person service items into our payload, but instead we chose to simplify by using the "PERSON_PATIENT" default payload. To do this, we use the Object.assign function to merge our payload contents with the content of the "PERSON_PATIENT" payload.

{
  payload: Object.assign({
    customScript: {
      script: [{name: '1_cancer_patients', run: 'pre', id: 'cancerpat', parameters:{}}] ,
      clearPatientSource: true
    },
    encounter: {
        aliases: true,
        prsnlReltn: true
    }},
    this.mpage.defaultPayload.get('PERSON_PATIENT')
    )
}

Controlling Data Collection with typeList

Data collection is quick and easy, however, it may not always be the most efficient. For example, you may want to collect the personAlias value for MRN and CMRN but nothing else. You can filter many data items down by type if you add typeList to your payload.

payload: {
    person: {aliases: true},
    typeList: [
      {codeSet: 4, type: 'MRN', typeCd: 0},
      {codeSet: 4, type: 'CMRN', typeCd: 0}
    ]
}

Each payload can have one typeList definition, and it can contain typeList filters for multiple code sets. For example, if your payload was also retrieving the person names data, and you only wanted to pull MAIDEN name, you could add code set 213 with a type of "MAIDEN" to filter the names.

The type field can either contain the CDF_MEANING or DISPLAY_KEY value of the code set being filtered. If you prefer, you can also directly enter the CODE_VALUE itself and leave the "type" field set to a value of "". We discourage putting code values directly into your code, however, you may have looked up a code value earlier in your code and may wish to use the value here instead of the textual name.

The available list of code sets allowed for each data service is listed in the service specific documentation.

Styling

The table below describes the styles specific to the MPage service that you can customize. These changes are global to your MPage. If you are building a component to be used in the Cerner MPage Component Framework, these styles are specific to your component and changes will have no impact on other Clinical Office components displayed on the same page.

SCSS Variable NameDefault ValueDescription
--notification-padding30vhPadding in notification message
--notification-font-weightboldNotification font weight
--notification-borderunsetBorder around notification
--notification-border-radius0Notification border radius
--notification-box-shadow
 
4px 4px 8px rgba(0, 0, 0, 0.3);
Box shadow around notification

Interfaces

MPageInstance {
  running: boolean;
  startTime: Date;
  calls: number;
  failedCalls: number;
  payload: string;
  result: string;
  request: any;
  callback: any;
  cclErrorReported: boolean;
  failedCall: boolean;
}
IPatientSource {
  personId: number;
  encntrId: number;
}
MPageLog {
  timestamp: Date;
  type: string;
  processId: number;
  statusText: string;
  text: string;
}
ITypeList {
  codeSet: number;
  type: string;
  typeCd: number;
}
<< Prev: Encounter
Next: Organization >>
Copyright © 2026 Precision Healthcare Solutions