Skip to main content

Developing Angular Widgets

This section describes how you can use Angular framework to develop your widgets.

Creating the Project#

About this task#

You can create a Web Component widget using Angular framework. The following instruction provides an example of creating a demo-web-component widget.

Procedure#

  1. Install Angular CLI running the command in your terminal ⁄ console. This will install the latest version of Angular available:
npm i -g @angular/cli
  1. Create a new Angular web component project file (demo-web-component in this case). As of Angular 17 the default app creation will create itself in standalone mode. This will not make use of an app.module file, however we want to enforce that the app.module file is created, hence the no-standalone flag. Note if prompted for stylesheets, press Enter key to select default CSS option and then N key to choose not to enable server-side rendering for this example.
// You can confirm the angular version used by running 'ng version' in the command line
// If running Angular 17+ run the following command instead
ng new demo-web-component --no-standalone
// If running Angular 14 or below then there is no need to specify flag
ng new demo-web-component
  1. Navigate to the project folder and run the following command:
npm install @angular/elements
  1. Create your Angular component:
ng g component my-web-component -v None
  1. Open your component and update View Encapsulation:
encapsulation: ViewEncapsulation.Emulated
  1. Navigate to /src/app directory and import the following elements into app.module.ts
import { Injector} from '@angular/core';
import { createCustomElement } from '@angular/elements';

Note Section 7 is only relevant if running Angular 14 or below, as defining entryComponents is no longer required in more recent Angular versions 7. Add an entryComponents array with your component inside:

entryComponents : [
MyWebComponent
]
  1. Remove the bootstrap array from the ngModule in app.module.ts.

  2. Transform the Angular component into a Web Component adding the following code to the AppModule class in app.module.ts:

constructor(private injector: Injector) {
const componentElement = createCustomElement(MyWebComponentComponent, { injector });
customElements.define('app-my-web-component', componentElement);
}

After importing the relevant dependencies your app.module.ts file should look like this:

import { DoBootstrap, Injector, NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { MyWebComponentComponent } from './my-web-component/my-web-component.component';
import { createCustomElement } from '@angular/elements';
@NgModule({
declarations: [
AppComponent,
MyWebComponentComponent
],
imports: [
BrowserModule,
AppRoutingModule
],
providers: [],
})
export class AppModule implements DoBootstrap {
constructor(private injector: Injector) {
const componentElement = createCustomElement(MyWebComponentComponent, { injector });
customElements.define('app-my-web-component', componentElement);
}
ngDoBootstrap(): void {}
}

Please note that this code will register the custom element when an instance of the Angular component is created. If you want to register the custom element when the application starts, you should move the custom element registration code to the main.ts file or another appropriate place in your application.

  1. Include the contents of your widget. You can use HTML, CSS, and JavaScript files.

Next step#

The component is now set up as a Web Component. At this point, the component files only contain the default Angular <my-web-component works!> example code. You can continue on with development in the HTML, JavaScript and CSS files. When your project is ready as a Web Component, you must build it for later use.

Building the Project#

About this task#

You must build the project to use your widget in Avaya Workspaces.

Procedure#

  1. From the root project folder, run the following command in your terminal / console:
ng build --output-hashing none

2a. If running Angular above version 14, then an alternate approach will be done, using a service called webpack

run

npm install --save-dev webpack webpack-cli
npm install --save-dev css-loader style-loader mini-css-extract-plugin

In the root project folder, create a webpack.config.js file with the following contents

/// webpack.config.js
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
entry: {
'demo-web-component': [
'./dist/demo-web-component/browser/polyfills.js',
'./dist/demo-web-component/browser/main.js',
'./dist/demo-web-component/browser/styles.css' // Add your CSS file here
]
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, './elements')
},
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader'],
},
],
},
plugins: [
new MiniCssExtractPlugin({
filename: '[name].css',
}),
],
optimization: {
minimize: false, // You can set this to true if you want to minify your output
},
mode: 'production'
};

Now update your package.json file with the following script and run npm run build:elements to build the project:

"build:elements": "ng build --output-hashing none && webpack --config webpack.config.js"

2b. If running Angular 14 or before, in the root project folder, create a concatenate.js file with the following contents if running Angular 14 or below:

const fs = require('fs-extra');
const concat = require('concat');
(async function build() {
const files = [
'./dist/demo-web-component/runtime.js',
'./dist/demo-web-component/polyfills.js',
'./dist/demo-web-component/main.js',
]
await fs.ensureDir('elements')
await concat(files, 'elements/demo-web-component.js');
await fs.copyFile('./dist/demo-web-component/styles.css', 'elements/styles.css')
})()

3b. Run the following command to install the required dependencies:

npm install fs-extra concat --save-dev

4b. Add the following build script into the package.json file. Note: When ran, it generates the Angular build files and uses the concatenate script to bundle them into a single file.

{
"scripts": {
"build:elements": "ng build --prod --output-hashing none && node concatenate.js"
}
  1. To build and bundle your project, create the elements folder running the following command:
npm run build:elements

Next step#

When your project is bundled and built, continue configuring the widget JSON file that you can import in the Avaya Workspaces Widget Manager.