npm package: @ibm-wch-sdk/ng-format
Description: Support package for @ibm-wch-sdk/ng to add ICU support for message translation.
Author: Dr. Carsten Leue
Latest version: 6.0.524

<a name="_6413c217ac070f0cc888ef237e5f77bca091ed14c4a6b017e8102394c2fc842d"></a>
# ibm-wch-sdk-ng-format

[![NPM version](https://badge.fury.io/js/ibm-wch-sdk-ng-format.svg)](https://npmjs.org/package/ibm-wch-sdk-ng-format)

Implementation of the `MsgFormatService` for [WCH](https://www.npmjs.com/package/ibm-wch-sdk-ng) based [Angular](https://angular.io/) applications that allows components to display text messages with replacements according to [ICU](http://userguide.icu-project.org/formatparse/messages). The service accepts a string that contains ICU replacement tokens and a context. It produces an [Observable](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html) with the replaced text against the context. If the replacement tokens are themselves `Observable`s, then the replaced text will be updated automatically.

## Usage

Install the module via

```bash
npm install --save ibm-wch-sdk-ng-format
```

Add the module to your root application

```typescript
@NgModule({
  ...
  imports: [
    ...
    WchNgMsgFormatModule.forRoot()
  ],
  ...
})
export class AppModule { }
```

## Prereqs

* [ibm-wch-sdk-ng](https://www.npmjs.com/package/ibm-wch-sdk-ng)
* Angular 4.0 or higher (including Angular 5)

## MsgFormatService

The service offers the API:

* `formatMessage(value: string, ctx: any) => Observable<string>`: that interprets the value as the ICU format string and replaces it against the given context.
  * `value`: the [ICU format](http://icu-project.org/apiref/icu4j/com/ibm/icu/text/MessageFormat.html) string
  * `context`: context object to resolve the variables in the template. The resolution will first convert each parameter to camel case. It then looks for an `onXXX` instance of type `Observable` on the context. If this does not exist, it looks for the camel case property `XXX` directly and falls back to the same sequence for the non-camel case version.

The locale of the translation is derived by the following process: first the service looks for an `onLocale` property of type `Observable`. If that does not exist, it falls back to `onRenderingContext` and extracts the locale property of the rendering context.

The fallback mechanism has been chosen such that it seamlessly works with layout components created by the [ibm-wch-sdk-ng](https://www.npmjs.com/package/ibm-wch-sdk-ng).

## Example

Consider a content item with a text field `myText` and a number field `myCount`. In the text field you'd like to enter text that depends on the actual number in the number field such as `Showing no items.` or `Showing 5 items`. This can be realized as follows:

### Text

The text in `myText` would look like `Showing {myCount, plural, =0{no items}, =1{one item}, other{# items}}.`.

### Components

The component defines accessors for the elements:

```typescript
export class MyComponent {

  @RenderingContextBinding('elements.myText.value')
  onMyText: Observable<string>;

  @RenderingContextBinding('elements.myCount.value')
  onMyCount: Observable<number>;
}
```

In the constructor define a derived property representing the replaced text:

```typescript
export class MyComponent extends AbstractRenderingComponent {

  @RenderingContextBinding('elements.myText.value')
  onMyText: Observable<string>;

  @RenderingContextBinding('elements.myCount.value')
  onMyCount: Observable<number>;

  onReplacedText: Observable<string>;

  constructor(aService: MsgFormatService) {
    super();

    this.onReplacedText = this.onMyText.switchMap(txt => aService.formatMessage(txt, this));
  }
}
```

In the HTML template use the replaced text attribute:

```html
<div>{{ onReplacedText | async }}</div>
```