NGX-PFE Features

1. State Storage

The PfeBusinessService is used to store and retrieve data in the application PfeStateService

It also provides observables for keys/expressions in the state.

The state can be automatically stored in the backend on every page switch. There is a spring boot starter plugin available that stores it in a redis database.

There is also a version of the state service that stores the states in a Dynamodb

By default the remote state is only updated with a specific Action. The enableAutomaticStateStorage flag in the module config allows it to enable an automatic update after every page navigation.

It is also possible to disable the state storage after a certain page in the flow. This can be used to exclude sensitive data from the backend storage.

If an application has a need for a more complex state handling, it is possible to provide a custom implementation of these services.

1.1. State expressions

To access values in the PFE state or any other JSON structure (like Service Activator responses) you will be using "expressions". These expressions are built on JSONPath, a querying language for JSON similar to XPath for XML. The expressions you can use in the PFE configuration exactly follow the rules of JSONPath expressions so please take a look at the documentation available at the previous link or the corresponding npm package.

If the result of your query is a single value then the PFE will return that value. This is not surprising when you imagine queries that access a single property in the state like $.myCustomKey. In case you have a more generic query that includes more advanced operators like "array slice" or "recursive descendant" than you will typically expect to get an array back. However, in this case the mentioned logic applies as well: If the result is a single value than you will receive that single value.

Let's look at an example to see why this matters:
Imagine our state contains an array of numbers at $.numbers. The expression $.numbers[::2] can be used to query every second number (take 1, skip 1, take 1, skip 1, ...). If we only have 2 numbers in the state this query will only yield a single number (the first one). By default all arrays that contain only a single element will be unwrapped by the PFE so as a result you would receive a single number (i.e. a return value of type number) - even though you asked for an array of numbers. If, however, the state contains 3 numbers that same query would yield an array with 2 elements. That means that, depending on the PFE state, you would receive a different type of data (number vs. Array<number>) which might add complexity to the receiving end of that query.

As shown there are certain expressions where it's reasonable to always expect an array. To overcome the default unwrapping-behavior you can instruct the PFE to keep the result as an array. To do so use the special array root []$ in your expression. For the above example: The query []$.numbers[::2] will always result in an array. If the result of a query is already an array than this syntax won't wrap it inside another array, so you don't need to fear nested arrays.

💡 This affects all queries. So even the return value for a very specific query like $.myCustomKey can be turned into an array using the array syntax: []$.myCustomKey.

1.2. Update State from Config

There is a possibility to update the state storage from the config, for that purpose you can define a list of updates that can be performed. It is also possible to apply those only with certain conditions.

  • StateUpdates
  • StateOperations

1.3. Update State from navigation

It is possible to update the the states values as part of the nextOptionList & backOptionList, as you can see in the example:

 {
      pageId: 'secondPageID',
      nextOptionList: [
        {
          nextPageId: 'thirdPageID',
          updateStateValues: [
            {
              key: `$.user`,
              value: 'Tobias',
            }
          ]
        }
      ],
      backOptionList: [
        {
          nextPageId: 'welcomePage',
          updateStateValues: [
            {
              key: `$.user`,
              operation: StateOperations.REMOVE
              conditions: [
                {
                  value1Expression: '$.inputFieldID',
                  operator: '===',
                  value2Expression: 'reset'
                }
              ],
            }
          ]
        }
      ]
    }

1.4. Update State from pageConfig

The same behavior is available as part of the page config.

const examplePageConfig: DemoAppPageConfig = {
  pageId: 'welcomePage',
  hideNextButton: false,
  hideBackButton: true,
  updateStateValues: [
    {
      key: `$.welcomePageReached`,
      value: true,
    },
  ],
  examplePageConfig: {
    firstConfigValue: 'This is the Page Title from the Configuration',
    secondConfigValue: 'Another text from configuration',
  },
};

Further examples of more complex configurations can be found in the viewer app of the pfe.

1.5. Update State from Components

this.pfeBusinessService.storeValueByExpression('$.mykey', 'value');

this.pfeBusinessService.getValueByExpression('$.myKey');

this.pfeBusinessService
    .getObservableForExpressionKey('$.mykey').subscribe(data => ...)

2. Service Activators

Service activators can be used to do http calls to the backend via pure configuration.

  • Data from the state can be sent to the backend via a mapping configuration
  • Response values from the backend can be written to the state via a mapping configuration
  • Service activators can be executed conditionally
  • Can be used to display server side validations on a page
  • Can be combined with the ngx-xtra dynamic form component to fill possible selections in a dropdown with a server side call.

Service Activators can also be triggered via PFE Actions.

Documentation of the configuration

The configuration of service activators is also supported by the config editor:

service activators in editor

2.1. Example for a Service Activator Configuration

{
  "pageId": "summary",
  "onPageLeaveServiceActivators": [
    {
      "path": "mo-bff/contract/process",
      "responseDataMapping": [
        {
          "responseDataExpression": "$.contractNumber",
          "stateKeyExpression": "$.contractNumber"
        }
      ]
    }
  ]
}

2.2. Error Handling with Service Activators

By default, a failure in a service activator call results in a redirect onto the global error page of the app. A failure is defined as any HTTP error response.

In general, the error handling can be configured in these locations:

  • Directly with the service activator in question
  • Globally. This is the default if no specific configuration is added to a service activator
Error Handling for a Specific Service Activator

The service activator configuration supports the definition of certain errorCases and how they should be handled.

This is done in the errorHandling attribute within the service activator configuration. The configuration itself defines an array of errorCases.

Every ErrorCase handling can define conditions that determine if it should become active or not. The first valid errorCase out of all configured ones is then executed.

The execution of an error case follows these steps:

  1. Run the errorResponseDataMapping configured in the errorCase. This allows it to save data from the payload of the response into the state. It works the same as the responseDataMapping for successful service activators.
  2. Execute the actions that are configured in the errorCase. This makes it possible to handle more specific behavior that is not covered by the standard configuration. The result of the action, directly translates to the behavior of the error handling. If the action returns true, the behavior is the same as with the ignoreError flag. If it returns false, the behavior is the same as with the disableErrorPageNavigation flag. An action can also trigger a custom navigation in this case. Alternatively, it is possible to ignore the action result with the ignoreActionsResult flag.
  3. After this, it is determined if the error should be ignored (ignoreError flag). In this case, no further error handling is done and the service activator behaves the same as a successful one.
  4. If the error was not ignored, it is checked if the error page navigation is disabled (disableErrorPageNavigation flag). For example: If the disableErrorPageNavigation is set for the error case of a service activator, that was triggered in the onPageLeave*, the navigation would be aborted and the user would stay on the current page.
  5. If these flags are not set, the errorPageNavigation of the service activator is used to determine the error page to go to. This navigation works similar to a standard navigation, but is able to access the payload of the error response.
  6. If there is no errorPageNavigation configuration, a fallback to the global error page is done.

A simple example configuration for a service activator with one error case could look like this:

{
  "onPageLeaveServiceActivators": [
    {
      "path": "errorServiceActivator",
      "errorHandling": {
        "errorCases": [
          {
            "conditions": [
              {
                "value1Expression": "$.response.status",
                "operator": "==",
                "value2Expression": "404"
              }
            ],
            "disableErrorPageNavigation": true
          }
        ]
      }
    }
  ]
}

In this example, the service activator runs into a 404 response. It is triggered when the page is left (onPageLeaveServiceActivators) As the disableErrorPageNavigation flag is set, the user will stay on the page and the navigation will be aborted in case of the 404 response.

Conditions of an errorCase

The configuration of the errorCase conditions are the same as the standard navigation conditions. They do however have a few extra gimmicks.

The state is only available under $.state in these conditions. The error response is available under $.response, which means that the response body for error responses is available under $.response.error.

The response headers are available under $.responseHeaders The data model for this can be found here: ErrorCaseConditionsState. They are converted into this structure: [index: string]: string[] The background for this is, that response headers can have duplicates. So the same header could have multiple values.

An example could look like this:

Response headers:

status: 400,
statusText:'error'
error: "Bad Request",
type: "REJECTION",
type: "this is a duplicate value of the type header"
message: "Http failure response for /path: 400 error",

These response headers are then converted to the following data model and provided to the conditions:

{
  "type": ["REJECTION", "this is a duplicate value of the type header"],
  "anotherHeader": ["something"]
}

In this example, we only want the error case to become active, if the type header is set, with the value REJECTION. If this value is not available, the error case should not become active.

This can be done with the following condition/expression:

{
  "value1Expression": "$.responseHeaders.type[?(@==\"REJECTION\")]"
}

This expression checks the values of the type header, if the value REJECTION is present.

To clarify, the following condition would lead to the same result. The extracted valued from the expression is REJECTION. This value is seen as truthy in the conditions.

{
  "value1Expression": "$.responseHeaders.type[?(@==\"REJECTION\")]",
  "operator": "==",
  "value2Expression": "REJECTION"
}

A full example of a service activator call with a more complex error handling of errors could look like this:

{
  "onPageLeaveServiceActivators": [
    {
      "path": "endpoint",
      "errorCases": [
        {
          "conditions": [
            {
              "value1Expression": "$.response.status",
              "operator": "==",
              "value2Expression": "400"
            },
            {
              "value1Expression": "$.responseHeaders.type[?(@==\"REJECTION\")]",
              "operator": "==",
              "value2Expression": "REJECTION"
            }
          ],
          "errorPageNavigation": [
            {
              "nextPageId": "errorPage"
            }
          ]
        },
        {
          "conditions": [
            {
              "value1Expression": "$.response.status",
              "operator": "==",
              "value2Expression": "400"
            }
          ],
          "disableErrorPageNavigation": true
        }
      ]
    }
  ]
}

This example configuration has the effect, that the user will only be navigated to the errorPage if the 400 response also contains the type header with the value REJECTION.

In all other cases, the navigation is stopped and the user stays on the page.

Actions

Actions that run within an error case can also influence the result of the error handling. If one of the actions returns a negative result (false), the error is thrown up. This has the same effect as the disableErrorPageNavigation flag.

errorPageNavigation

An example for a custom errorPageNavigation could look like this:

{
  "onPageLeaveServiceActivators": [
    {
      "path": "endpoint",
      "errorCases": [
        {
          "conditions": [
            {
              "value1Expression": "$.response.status",
              "operator": "==",
              "value2Expression": "500"
            }
          ],
          "errorPageNavigation": [
            {
              "nextPageId": "myCustomErrorPage",
              "conditions": [
                {
                  "value1Expression": "$.response.error.thisServer",
                  "operator": "==",
                  "value2Expression": "isCrashed"
                }
              ]
            },
            {
              "nextPageId": "fallbackErrorPage"
            }
          ]
        }
      ]
    }
  ]
}

The navigation to the myCustomErrorPage only happens if the response body contains the text isCrashed in the field thisServer for the response with the status code 500. If that is not the case, the default fallbackErrorPage is used.

Global Error Page Configuration

The errorPageNavigation configuration can be used to define conditions that determine the error page that should be displayed.

Example for such a configuration:

{
  "navConfiguration": {
    "errorPageNavigation": [
      {
        "nextPageId": "teapotError",
        "conditions": [
          {
            "value1Expression": "$.response.status",
            "operator": "===",
            "value2Expression": "418"
          }
        ]
      },
      {
        "nextPageId": "defaultErrorPage",
      }
    ]
  }
}

The conditions to determine if a navigation to an error page should happen are similar to the NavOptionConfig conditions. But in difference to those, the PFE state is only available under $.state in the error page navigation conditions.

Additionally the response data is available:

  • The error response is available under $.response
  • The http status is available under $.response.status
  • The response body for error responses is available under $.response.error
  • The response headers under $.responseHeaders

The errorResponseDataMapping in the errorCases configuration of a specific service activator can be used to write the error response data to the state before the error page navigation is triggered.

Example for a Service Activator for a Validation

The user will only be able to navigate, once the service returned a non-error response

{
  "path": "some-service/validate",
  "serviceActivatorMethod": "POST",
  "preventNavigationOnError": true,
  "requestDataMapping": [
    {
      "requestDataExpression": "$.fieldToValidate",
      "stateKeyExpression": "$.userdata.fieldToValidate"
    },
    {
      "requestDataExpression": "$.anotherFieldToValidate",
      "stateKeyExpression": "$.userdata.anotherFieldToValidate"
    }
  ],
  "responseDataMapping": [
    {
      "responseDataExpression": "$",
      "stateKeyExpression": "$.someService.validationStatus"
    }
  ],
  "serviceActivatorErrorHandlingExcludeStatusCodes": [404, 400],
  "serviceActivatorResponseStatusHandlers": [
    {
      "statusCode": 400,
      "stateKeyExpression": "$.validationErrorData",
      "stateValue": "common.validation.formatError"
    },
    {
      "statusCode": 404,
      "stateKeyExpression": "$.validationErrorData",
      "stateValue": "common.validation.notFoundError"
    }
  ]
}

2.3. Trigger Service Activators Through Code

While it is recommended to rely on the trigger points of the navigation flow, it is also possible to trigger service activators directly in the code. The PfeBusinessService provides the triggerSingleServiceActivator() for this.

It can be used like this:

this.pfeBusinessService
  .triggerSingleServiceActivator('serviceActivatorID')
  .then((response) => {
    // The full HTTP response of the service activator is available here
  })
  .catch((error) => {
    // The full HTTP error response of the service activator is available here
  });

By default, the PFE error handling is active for every service activator. That means an automatic navigation to the error page is triggered.

It might be desirable to stay on the current page, for example if the error is supposed to be handled manually in the code of the catch block. This can be done, by disabling the navigation to the error page for the service activator in question. For example:

{
  "errorServiceActivator": {
    "path": "http://example.com/this-is-a-404",
    "serviceActivatorMethod": "GET",
    "errorHandling": {
      "errorCases": [
        {
          "disableErrorPageNavigation": true
        }
      ]
    }
  }
}

3. PFE Actions

The PFE Actions are a set of actions that the PFE can execute on certain events, like a user entering or leaving, a page. The actions can then trigger Service Activators, state values updates and more. The benefits is, that everything can be mixed and it is also possible to add custom actions in an app using the PFE.

A custom action can be any function within an app.

Actions can also be triggered directly in the code via the PfeActionsService

3.1. Triggering Service Activators through an Action

For example, if a service activator configuration looks like this:

{
  "pageId": "examplePage",
  "onPageEnterServiceActivators": [
    {
      "globalConfigID": "exampleServiceActivator"
    }
  ]
}

It will look like this, with the pfeActions:

{
  "pageId": "examplePage",
  "onPageEnterActions": [
    {
      "type": "TRIGGER_SERVICE_ACTIVATORS",
      "serviceActivators": [
        {
          "globalConfigID": "myID"
        }
      ]
    }
  ]
}

3.2. Updating State Values

An updateStateValues configuration can also be handled with an action.

This configuration:

{
  "pageId": "examplePage",
  "updateStateValues": [
    {
      "key": "$.foo",
      "value": "bar"
    }
  ],
  "pageConfig": {}
}

Would turn into this action:

{
  "pageId": "examplePage",
  "onPageEnterActions": [
    {
      "type": "UPDATE_STATE_VALUES",
      "stateUpdates": [
        {
          "key": "$.foo",
          "value": "bar"
        }
      ]
    }
  ]
}

3.3. onNavigationStartActions

onNavigationStartActions can use conditions to determine the target page of a navigation. Dependent on this, they can be executed or not.

The necessary information is available with the $._pfe.navigationState.navigatingTo expression in the state.

See also the Order of Execution chapter for more information

{
  "pageId": "navigationActionsPage",
  "onNavigationStartActions": [
    {
      "type": "BLOCKING_ACTION",
      "message": "Action: Shall we continue to the dead end?",
      "conditions": [
        {
          "value1Expression": "$._pfe.navigationState.navigatingTo",
          "operator": "==",
          "value2Expression": "deadEndPage"
        }
      ]
    }
  ]
}

3.4. onPageEnterActions Navigation Conditions

onPageEnterActions can check against the previous page in their conditions.

{
  "pageId": "onPageEnterActionsPage",
  "onPageEnterActions": [
    {
      "type": "BLOCKING_ACTION",
      "message": "Welcome back from the dead end!",
      "conditions": [
        {
          "value1Expression": "$._pfe.navigationState.navigatingFrom",
          "operator": "==",
          "value2Expression": "deadEndPage"
        }
      ]
    }
  ]
}

Limitations

This information is not available (undefined) when the previous page is outside the pfe flow.

3.5. Pre Registered pfeActions

The pfe provides a few default actions:

3.6. Optional Actions

There are also 2 optional actions that are not registered by default, but can be imported in an app:

3.7. Implementation of Custom Actions

An action simply triggers a function in the code.

Follow these steps, to add a custom action:

Create a Configuration Data Model

Every action defines a custom configuration data model.

The data model consists of two parts:

  1. The type of the action
  2. The configuration interface

The type is used for the mapping of the configuration to the actual action.

The configuration data model is also integrated into the json-schema. This makes it possible to validate the configuration and to provide autocomplete for available attributes in the configuration.

The model extends the PfeBaseActionConfig.

servus.model.ts

import { PfeBaseActionConfig } from '@allianz/ngx-pfe';

export const ServusActionType = 'SERVUS';

export interface PfeServusActionConfig extends PfeBaseActionConfig {
  type: typeof ServusActionType;
  /**
   * Comments in the configuration model will also be a part of the json-schema.
   */
  name: string;
}

Implement an Action Function

An action is simply a function that is triggered by the pfe.

While not required, it is common practice to locate the function within an Angular service, which also makes it possible to access other dependencies.

An action function needs to implement the PfeActionFunction, which looks like this:

export type PfeActionFunction = (actionConfig: PfeBaseActionConfig) => Promise<void | boolean>;

It needs to return a Promise. The pfe will wait for this promise to be resolved. Actions are ran one after each other in the configured order.

The promise itself can either be empty (void) or contain a boolean. If it contains a boolean, the result will be used to determine if the navigation should be continued. If it is false, the navigation is aborted.

A void response is assumed to be true, which will allow the navigation to continue.

The mechanism and behavior of this is similar to Angular route guards. This means, if an onPageLeave stops the navigation and doesn't trigger anything else, the user will just stay on the current page and can try it again. It is also possible to trigger another navigation from within the action.

Actions have one parameter, the actionConfig. It contains the configuration of the action, which follows the defined data model.

servus.service.ts

import { Injectable } from '@angular/core';
import { PfeServusActionConfig } from './servus.model';

@Injectable({
  providedIn: 'root',
})
export class PfeServusService {
  constructor() {}

  public executeServus = async (actionConfig: PfeServusActionConfig): Promise<void> => {
    console.log(`Servus ${actionConfig.name}`);
  };
}

After that, the action needs to be registered with the PfeActionsService. This can happen at any time before the action is triggered. For example it could be done in the app.module constructor.

import { PfeActionsService } from  '@allianz/ngx-pfe';
import { PfeServusService } from  './servus.service';
import { ServusActionType } from  './servus.model';

...
constructor(
    private pfeActionsService:  PfeActionsService,
    private pfeServusService: PfeServusService
) {
    this.pfeActionsService.registerAction(ServusActionType, this.pfeServusService.executeServus)
}

The action can now be used in the navigation.json:

{
  "onPageEnterActions": [
    {
      "type": "SERVUS",
      "name": "Alvaro"
    },
    {
      "type": "SERVUS",
      "name": "Tobi"
    }
  ]
}

3.8. Global Actions

Its possible to use global actions on a very similar way as the global service activators.

It is recommended to use the the ConfigAggregator, which works like this:

Example of global action on file /actions/servus.json

{
  "actionId": "servus",
  "type": "SERVUS",
  "name": "Alexander"
}

And in the navigation json:

{
  "onPageLeaveActions": [
    {
      "globalConfigId": "servus"
    },
    {
      "globalConfigId": "servus",
      "name": "Hamilton"
    }
  ]
}

Updating the JsonSchema

The custom actions can also be reflected in the navigation.json json-schema.

To do that, we need to create a new file, and then create the json schema from that ``xxx-navigation.model.ts`

import { PageNavigationConfiguration, PfeNavigationConfiguration } from '@allianz/ngx-pfe/models/navigation-config.model';

export type XXXActionConfig = PfeActionConfig | ServusAction;
export interface XXXNavigationConfiguration extends PfeNavigationConfiguration<XXXActionConfig> {}
export interface XXXPageNavigationConfiguration extends PageNavigationConfiguration<XXXActionConfig> {}

4. How to Intercept the Navigation

TL;DR: Use PFE Actions that return a Promise<boolean> to intercept a navigation.

There are multiple ways to intercept a navigation:

  • PFE Actions
  • Angular Route Guards

Actions can be configured in the navigation, whereas route guards are configured on a page level.

âš  Careful! âš  If an action stops the navigation from within the firstPage mechanism, it will automatically fallback to the error page.


Known Issues: There's some known Angular issues around route guards/pfe action guards, if the navigation was triggered with the browser buttons. Dependent on the user interaction, the navigation history might get corrupted. This is especially the case when the forward browser button is used.

Further information:

The pfe already contains workarounds for the backward navigation and these might be extended at some point to cover more cases.

4.1. Execution Order

When leaving a page the execution order is:

  1. PFE Actions & Service Activators
  2. Route Guards

When entering a page, the execution order is:

  1. Route Guards
  2. PFE Actions & Service Activators

4.2. Configuration of Route Guards

The PFE allows to create custom Angular route guards that can be applied to each page in the configuration.

Route guards can trigger on activation or deactivation of a route.

âš  Careful! âš  The deactivation of a route happens after leave actions like the onPageLeaveAction or onPageLeaveServiceActivator are executed! If these should also be intercepted a pfeAction can be used.

An activation route guard however, runs before the pfe code and can therefore also intercept those actions.

Follow these steps, to integrate custom route guards in an app:

  1. Create an enum with different keys per each guard that should be defined. After that, specify the enum in the page definition.
export enum GUARD_KEYS {
  PFE_EXAMPLE_CAN_LOAD = 'PFE_EXAMPLE_CAN_LOAD',
  PFE_EXAMPLE_CAN_ACTIVATE = 'PFE_EXAMPLE_CAN_ACTIVATE',
}

export interface DemoAppPageConfig extends PageConfig<GUARD_KEYS> {}

This will make it possible to get autocomplete for the guards in the json-schema.

  1. The mapping of the guard keys enum to the actual guard class needs to be set with the PFE_GUARDS_CONFIG Injection Token provided by the PFE.
import { PFE_GUARDS_CONFIG } from '@allianz/ngx-pfe';

providers: [
  {
    provide: PFE_GUARDS_CONFIG,
    useValue: {
      PFE_EXAMPLE_CAN_LOAD: LoadTestGuard,
      PFE_EXAMPLE_CAN_ACTIVATE: ActivateTestGuard,
    },
  },
];
  1. The guards can now be used in the page config with their specified key. The json-schema provides autocomplete on the possible keys.
{
  "pageId": "pageWithRouteGuard",
  "hideNextButton": true,
  "myPageType": {
    "myConfig": "value"
  },
  "guards": {
    "canActivate": ["PFE_EXAMPLE_CAN_ACTIVATE"],
    "canLoad": ["PFE_EXAMPLE_CAN_LOAD"]
  }
}

5. Display of Validation Messages on the Master page

It is possible, to display generic error messages above the currently displayed page.

The master pages checks the state for a configurable key. If no key is configured, the fallback validationErrorData is used.

If a value is added to this state key, the message gets displayed. To remove the message, set the key to an undefined/empty value. All values from these keys are translated with ngx-translate.

In combination with the service activators, a response can be written to the state and displayed as a validation message.

Use the serviceActivatorErrorHandlingExcludeStatusCodes configuration in the AppConfiguration PfeConfig to define http status codes that should not be treated as an error that redirects to the error page.

6. Page Status for Navigation to the Next Page

When a page is opened, the status of the page is set to invalid by default. This will also prevent the navigation to the next page.

For the navigation to be allowed, the page status has to be set by calling setPageStatus():

pfeBusinessService.setPageStatus(<boolean>);

If a page contains a form with mandatory fields, this status can be tied to the validity of the form to prevent a navigation as long as the form is invalid.

7. URL Parameters

The PFE supports multiple different URL parameters.

These can be used to switch the tenant/applicationID, to supply a state ID or to transfer parameters into the state.

It is also possible to add a configuration, that copies custom url parameters into the state during startup

The configuration is located in the pfeConfig within the application config (usually application.json or pfe.json).

For example:

"pfeConfig": {
  "urlParametersInState": [
    {
      "key": "myCustomURLParameter",
      "stateKeyExpression": "$.myCustomURLParameterInTheState"
    },
    {
      "key": "anotherParameter",
      "stateKeyExpression": "$.savedInTheState"
    }
  ]
},

8. NGX-PFE Developer Tools

Additionally, the library contains the pfe-dev-tools which contain functionality to simplify the creation of a page flow configuration.

These can be integrated in the following way:

<pfe-dev-tools></pfe-dev-tools>

The import PfeDevToolsModule needs to imported from a secondary entry point:

import { PfeDevToolsModule } from '@allianz/ngx-pfe/pfe-dev-tools';

By default, the development tools have to be activated with the devtools=true URL parameter.

It is also possible to always activate them:

<!-- prettier-ignore-start -->
<pfe-dev-tools [devToolsActive]="true"></pfe-dev-tools>
<!-- prettier-ignore-end -->

It is recommended, to restrict them to the local/dev/staging environment. This could be done, in the following way:

// prettier-ignore
<div *ngIf="(environment?.env === 'local') || (environment?.env === 'dev') || (environment?.env === 'staging')">
  <pfe-dev-tools></pfe-dev-tools>
</div>

8.1. Log State Hotkey

The current state can be logged with the following hotkey: [ctrl]+[alt]+[l] or [cmd]+[alt]+[l]

9. Enable Logs

Since version v11.0.9 PFE changes the console.log for the new @allianz/ngx-logger It is possible to supply a custom logging config.

results matching ""

    No results matching ""