Angular 11+ powered owl-carousel
npm install ngx-owl-carousel-2ngx-owl-carousel-o is built for Angular >=6.0.0. It doesn't use jQuery.
| ngx-owl-carousel-o | Angular |
| ---------------------- | ------- |
| 5.x.x | 11.x.x |
| 4.x.x (latest 4.0.0) | 10.x.x |
| 3.x.x (latest 3.1.1) | 9.x.x |
| 2.x.x (latest 2.1.1) | 8.x.x |
| 1.x.x (latest 1.2.1) | 7.x.x |
| 0.x.x (latest 0.1.2) | 6.x.x |
- Get started
- Setting custom slides ids
- Options
- Tag in the slide. Directive owlRouterLink
- Events
- Plugins
- Tips
- ReferenceError: Event is not defined
1. Run yarn add ngx-owl-carousel-o or npm install ngx-owl-carousel-o or ng add ngx-owl-carousel-o.
2. Add styles (one of these variants).
- angular.json:
``json`
"styles": [
"node_modules/ngx-owl-carousel-o/lib/styles/prebuilt-themes/owl.carousel.min.css",
"node_modules/ngx-owl-carousel-o/lib/styles/prebuilt-themes/owl.theme.default.min.css",
"src/styles.sass" or "src/styles.css"
],
- src/styles.sass or src/styles.scss:
`sass`
@import '~ngx-owl-carousel-o/lib/styles/scss/owl.carousel';
@import '~ngx-owl-carousel-o/lib/styles/scss/owl.theme.default';
3. Import RouterModule and Routes into AppModule unless they are imported.BrowserAnimationsModule
4. Import into AppModule unless it is imported.CarouselModule
5. Import into a module which declares a component intended to have a carousel.
`typescript`
import { CarouselModule } from 'ngx-owl-carousel-o';
@NgModule({
imports: [CarouselModule],
declarations: [CarouselHolderComponent],
})
export class SomeModule {}
6. Add to needed component customOptions or named in different way object with options for the carousel:
`typescript`
import { OwlOptions } from 'ngx-owl-carousel-o';
@Component({
selector: '....',
templateUrl: 'carousel-holder.component.html',
})
export class CarouselHolderComponent {
customOptions: OwlOptions = {
loop: true,
mouseDrag: false,
touchDrag: false,
pullDrag: false,
dots: false,
navSpeed: 700,
navText: ['', ''],
responsive: {
0: {
items: 1,
},
400: {
items: 2,
},
740: {
items: 3,
},
940: {
items: 4,
},
},
nav: true,
};
}
7. Add html-markup to the template of the component (in this case, add it to carousel-holder.component.html):
`html`
Some tags before
Some tags after
or
`html`
Some tags before
Some tags after
NOTE: Each slide has an id. If it isn't supplied like in the first example given to p. 7, the code generates it automatically and expose one when thetranslated
event fires. Info about this event is below. Follow the link event translated.
NOTE: Custom id must have the type string.
NOTE: Using ngx-owl-carousel-o with options animateOut and animateIn requires adding animate.css. Steps are the following:
1. yarn add animate.css or npm install animate.css.angular.json
2. Add styles to :
`json`
"styles": [
"node_modules/animate.css/animate.min.css"
],
It's possible to set own id to every slide.
> Every id must have the type string. Otherwise, slides won't get ids what will cause one problem, which appears when the developer uses the optionresponsive
> . Slides won't be shown when the width of the screen changes and the carousel has to apply new settings according to the defined breakpoint. Thisid
> is because the code uses ids of slides in order to assign new data to slides. So if you change the width of the screen and slides disappear, there could be
> the problem with setting . id
> If s aren't set explicitly, they will be created automatically.
The example of setting ids:
`html`Some tags before
Some tags after
ngx-owl-carousel-o uses the same options as Owl Carousel. Explanations of meanings and the usage of options are in
Owl Carousel Documentation.
NOTE: ngx-owl-carousel-o has the different usage of some of them. Mostly this is about options which require setting data- attributes to DOM-elements
and which set names of classes and tags in the HTML-markup. The usage of these options is explained below.
Options which require setting data- attributes are:
- merge
- dotsData
- URLhashListener
- lazyLoad
The original Owl Carousel requires setting data-merge to each slide besides setting merge=true. In this lib data-merge is changed to dataMerge , which@Input
is the property of the directive. The way of setting it is:
`html`
the number must be 1, 2, 3 or any other integer numbers. If dataMerge isn't provided, its value will be 1 (this is the default value).
The option autoWidth=true is working if user sets the @Input prop width to directive. The example:
`html`
When the width isn't provided for a certain slide and is provided for other slides, firstly it will be 0 (this is the default value). At the end it will becarouselWidth=1200
calculated as (width of carousel)/(items) (e.g. and items=4, the width of the slide will be 1200/4=300).
In other words, the width of the slide with unprovided width will be set according to how much space in visible carousel window the slide must take. E.g. if
there must be 2 visible slides, the width of the item will be half of the carousel window.
The option responsiveBaseElement doesn't work. In the original Owl Carousel, all responsive breakpoints are corresponding to window width. Here they are
corresponding to the width of the element
which takes 100% of its parent element width.$3
The option
fallbackEasing doesn't work because it's being used by $.animate() in Owl Carousel created by means of jQuery. There's no such function in
Angular.$3
The option
info doesn't work.$3
These options don't work.
| Option | Explanation |
| ------------------------------------ | ----------------------------------------------------------------- |
| navElement: 'div' | this tag is set explicitly in the View of CarouselComponent |
| navContainer: false | is removed |
| navContainerClass: 'owl-nav' | this css-class is set explicitly in the View of CarouselComponent |
| navClass: [ 'owl-prev', 'owl-next' ] | this css-class is set explicitly in the View of CarouselComponent |
| dotClass: 'owl-dot' | this css-class is set explicitly in the View of CarouselComponent |
| dotsClass: 'owl-dots' | this css-class is set explicitly in the View of CarouselComponent |
| dotsContainer: false | is removed |
$3
The option
nestedItemSelector doesn't work.$3
These options don't work.
| Option | Explanation |
| ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| itemElement: 'div' | this tag is set explicitly in the View |
| itemClass: 'owl-item' | this css-class is set explicitly in the View |
| stageElement: 'div' | this tag is set explicitly in the View |
| stageClass: 'owl-stage' | this css-class is set explicitly in the View |
| stageOuterClass: 'owl-stage-outer' | this css-class is set explicitly in the View |
| | |
| refreshClass: 'owl-refresh' | this css-class is removed. Class 'owl-refreshed' is used instead. It's set explicitly in the View and reflected by OwlDOMData.isRefreshed |
| loadedClass: 'owl-loaded' | this css-class is set explicitly in the View and reflected by OwlDOMData.isLoaded |
| loadingClass: 'owl-loading' | this css-class is set explicitly in the View and reflected by OwlDOMData.isLoading |
| rtlClass: 'owl-rtl' | this css-class is set explicitly in the View and reflected by OwlDOMData.rtl |
| responsiveClass: 'owl-responsive' | this css-class is set explicitly in the View and reflected by OwlDOMData.isResponsive |
| dragClass: 'owl-drag' | this css-class is set explicitly in the View and reflected by OwlDOMData.isDragable |
| grabClass: 'owl-grab' | this css-class is set explicitly in the View and reflected by OwlDOMData.isGrab |
$3
NOTE: Setting options in the HTML-template in the way like
`html
', '
Slide
`will cause the template parse error because of the double quote put around classes's names _fa-chevron-left_ and _fa-chevron-right_. The creation of the
property e.g.
customOptions in component.ts and writing [options]="customOptions" will eliminate this problem.`typescript
customOptions: OwlOptions = {
navText: ['', '};
`and
`html
Slide
`$3
It's needed to set it to
true and to set the content in the dot for every slide using the @Input property dotContent:`html
Slide 1
`- in the case when
content is the prop of a component.`html
Slide 1
`- in the case when
content is simple text.The ontent can be simple text or the HTML-markup. Dots with this option work as tabs. The option
items should be set to 1, otherwise, scrolling of slides will
be done by pages (1 page equals the number of visible slides). If the dotContent isn't provided in , its values will be ''
(this is the default value).$3
When there's the option
slideBy='page', disabled prev or next buttons will rewind the carousel to the start or the end accordingly. When the number of
pages (dots) is 2 and there's the option loop=false, changing pages could cause thoughts something is wrong (when the carousel is on the first page, click on
the prev button makes the carousel show the second page which is the ending of the carousel at the same time; in this case the next and prev button
do the same job). To avoid this behavior, the number of pages must be 3 and more or it's needed to set loop=true.The number of pages depends on the number of all slides and the option
items (e.g. if the quantity of slides is 10 and items=3, the number of pages will
be 4 (10/3=3.3; 3.3 is rounded to 4)).$3
The documentation of Owl Carousel says the default value of this option is set to
true, but the code defines it as false. In ngx-owl-carousel-o, its
default value is set to false.WARNING: options
rewind and loop shouldn't be enabled in one carousel. They do a similar job in different ways.$3
The option
freeDrag doesn't have the realization. Thus setting it to true will give nothing. This option doesn't work even in Owl Carousel written by means
of jQuery.$3
The option
autoplayTimeout must always be bigger than the option autoplaySpeed. Otherwise, the autoplay won't work.$3
This options works just in the case
autoplayHoverPause is enabled. autoplayMouseleaveTimeout sets the value of just the first timeout after firing the event
mouseleave. Default meaning is 1. Then the value of autoplayTimeout is applied.$3
When the option
URLhashListener=true, it's required to define the @Input prop dataHash in :`html
Slide 1
Slide 2
` or
`html
Slide 1
Slide 2
`where
hashObj is the object with hashes (fragments) of url. hashObj could be an array. Defining the kind of data store is up to the developer.NOTE:
HashService uses services ActivatedRoute and Router for making it possible to navigate by hashes (fragments). And if
RouterModule.forRoot(routes) isn't imported in the main module of an application, the problem will appear. HashService won't work. Therefore it's needed
to import RouterModule.forRoot(routes) in the main module of an application even in the case of creating the simple app for testing the work of the library.$3
There's no need to set to
attributes data-src and data-src-retina because Angular has its own realization for . In Angular it's better to
write . src is the data-binding, which means Angular will set the value to the native attribute src of after loading its core
code. Original Owl Carousel reads data-src and sets the native attribute src at needed moment. Of course, ngx-owl-carousel-o has additional tricks for
lazy loading images (better to say the content of slides) put into slides.$3
By default, this option is set to
false. This option changes the number of visible slides in the case, when the number of slides is less than the value of the
option items. For example, when the items=4 and there're just 3 slides, the carousel will reassign the value of items to 3.When the option
skip_validateItems is true, the carousel won't reassign the items. So, in the example above items will remain 4. But there will be 3
slides and one empty place. This for the case when the option loop=false. When loop=true, the empty place will be populated by the copy of the first slide.owlRouterLink
The directive
owlRouterLink is introduced for making impossible the navigating between components while the carousel is dragging.This directive has the same features as the native
routerLink directive. One exception is the property stopLink. It prevents the navigating to another
component.This directive is included into
CarouselModule, which must be imported into a needed module before using the ngx-owl-carousel-o. So, to use this directive,
you just need to write it inside the needed slide.Example of usage this directive:
`html
`{{item.text}} contains owlRouterLink directive and its _@Input_ property stopLink.{{item.text}} is also possible way of using this directive.In the example above, we see the usage of
dragging event, owlRouterLink, and stopLink. When the dragging of the carousel starts, the dragging event
notifies about it by passing object`typescript
{
dragging: true,
data: {}
}
`The value of the prop
dragging is assigned to the isDraggable property. Then this property is passed into owlRouterLink through stopLink. Directive gets
aware of dragging the carousel and prevents any navigations.When the dragging of the carousel is finished,
dragging passes object`typescript
{
dragging: false,
data: {}
}
`isDraggable gets updated, which causes the change of stopLink. Now its value is false. This enables navigating during the next simple click on
locating in the slide unless new dragging starts.So, to use
in any slide, it's recommended to:- use
dragging event and property isDragging (or named differently);
- use owlRouterLink directive;
- use stopLink property of owlRouterLink. It's needed to pass to this prop isDragging. Using of stopLink is required.The real example is here.
The
has the automatic preventing navigation during dragging.Events
- translated.
- dragging.
- change.
- changed.
- initialized.
$3
It fires after the carousel finishes translating and exposes the object of the type
SlidesOutputData.`typecript
class SlidesOutputData {
startPosition?: number;
slides?: SlideModel[];
};
`startPosition is the position of the first slide with the class .activeslides is the array with data of each active slide. Data of each active slide are:`typescript
{
id: string; // id of slide
width: number; // width of slide
marginL: number; // margin-left of slide
marginR: number; // margin-right of slide
center: boolean; // whether slide is centered (has .center)
}
`The code for subscribing to this event is the following:
CarouselHolderComponent`typescript
import { SlidesOutputData, OwlOptions } from 'ngx-owl-carousel-o';
@Component({
selector: '....',
template: ,
})
export class CarouselHolderComponent {
customOptions: OwlOptions = {
loop: true,
mouseDrag: false,
touchDrag: false,
pullDrag: false,
dots: false,
navSpeed: 700,
navText: ['', ''],
responsive: {
0: {
items: 1,
},
400: {
items: 2,
},
740: {
items: 3,
},
940: {
items: 4,
},
},
nav: true,
}; activeSlides: SlidesOutputData;
slidesStore: any[];
constructor() {}
getPassedData(data: SlidesOutputData) {
this.activeSlides = data;
console.log(this.activeSlides);
}
}
`(translated)="getPassedData($event)" is the subscription or attaching to the event;getPassedData(data: SlidesOutputData) is the method which takes data about active slides.activeSlides is the property of CarouselHolderComponent, which stores data about active slides$3
The event
dragging fires after that the user starts dragging the carousel. It exposes the object`typescript
{
dragging: boolean,
data: SlidesOutputData
}class SlidesOutputData {
startPosition?: number;
slides?: SlideModel[];
};
`When the dragging of the carousel is started its paylod is:
`typescript
{
dragging: true,
data: {
startPosition: 0,
slides: [ slide, slide, slide ];
}
}
`The prop
data shows the situation which was at the moment of starting dragging. In other words, if before dragging the carousel the prop startPosition was
0, the event dragging will emit this prop with the same value.When the dragging of the carousel is finished and the event
translated is fired dragging fires again but its payload has value`typescript
{
dragging: false,
data: {
startPosition: 1,
slides: [ slide, slide, slide ];
}
}
`This time, the prop
data shows current startPosition and current active slides.This event is needed for the cases when slide should contain the tag
with the routerLink directive.Example of using this event:
`html
`(dragging)="isDragging = $event.dragging" This expression uses the dragging event and has the property isDragging which should be created in the component
hosting the .$event is the payload of the event. Its prop dragging can be true or false. The real example is
here.$3
It fires after the carousel gets initialized and exposes the object of the type
SlidesOutputData.`typecript
class SlidesOutputData {
startPosition?: number;
slides?: SlideModel[];
};
`startPosition is the position of the first slide with the class .activeslides is the array with data of each active slide. Data of each active slide are:`typescript
{
id: string; // id of slide
width: number; // width of slide
marginL: number; // margin-left of slide
marginR: number; // margin-right of slide
center: boolean; // whether slide is centered (has .center)
}
`The code for subscribing to this event is the following:
CarouselHolderComponent`typescript
import { SlidesOutputData, OwlOptions } from 'ngx-owl-carousel-o';
@Component({
selector: '....',
template: ,
})
export class CarouselHolderComponent {
customOptions: OwlOptions = {
loop: true,
mouseDrag: false,
touchDrag: false,
pullDrag: false,
dots: false,
navSpeed: 700,
navText: ['', ''],
responsive: {
0: {
items: 1,
},
400: {
items: 2,
},
740: {
items: 3,
},
940: {
items: 4,
},
},
nav: true,
}; activeSlides: SlidesOutputData;
slidesStore: any[];
constructor() {}
getData(data: SlidesOutputData) {
this.activeSlides = data;
console.log(this.activeSlides);
}
}
`(initialized)="getData($event)" is the subscription or attaching to the event;getData(data: SlidesOutputData) is the method which takes data about active slides.activeSlides is the property of CarouselHolderComponent, which stores data about active slides$3
It fires after each change in the carousel (click on dots, nav buttons). However, while the user drags the carousel this event fires after dropping the carousel
or after stopping dragging. This event exposes the object of the type
SlidesOutputData. It's populated by data defined before firing the event. This event
just notifies about changes. New data (active slides, startPosition) gets available after the end of moving the carousel (event translated).`typescript
class SlidesOutputData {
startPosition?: number;
slides?: SlideModel[];
}
`startPosition is the position of the first slide with the class .activeslides is the array with data of each active slide. Data of each active slide are:`typescript
{
id: string; // id of slide
width: number; // width of slide
marginL: number; // margin-left of slide
marginR: number; // margin-right of slide
center: boolean; // whether slide is centered (has .center)
}
`The code for subscribing to this event is the following:
CarouselHolderComponent`typescript
import { SlidesOutputData, OwlOptions } from 'ngx-owl-carousel-o';
@Component({
selector: '....',
template: ,
})
export class CarouselHolderComponent {
customOptions: OwlOptions = {
loop: true,
mouseDrag: false,
touchDrag: false,
pullDrag: false,
dots: false,
navSpeed: 700,
navText: ['', ''],
responsive: {
0: {
items: 1,
},
400: {
items: 2,
},
740: {
items: 3,
},
940: {
items: 4,
},
},
nav: true,
}; activeSlides: SlidesOutputData;
slidesStore: any[];
constructor() {}
getData(data: SlidesOutputData) {
this.activeSlides = data;
console.log(this.activeSlides);
}
}
`(change)="getData($event)" is the subscription or attaching to the event;getData(data: SlidesOutputData) is the method which takes data about active slides.activeSlides is the property of CarouselHolderComponent, which stores data about active slides$3
It fires when user clicks dots or nav buttons and new data about active slides becomes known. This event fires before the event
translated gets fired.
However, while the user drags the carousel this event fires after dropping the carousel or after stopping dragging. This event exposes the object of the type
SlidesOutputData:`typescript
class SlidesOutputData {
startPosition?: number;
slides?: SlideModel[];
}
`startPosition is the position of the first slide with the class .activeslides is the array with data of each active slide. Data of each active slide are:`typescript
{
id: string; // id of slide
width: number; // width of slide
marginL: number; // margin-left of slide
marginR: number; // margin-right of slide
center: boolean; // whether slide is centered (has .center)
}
`The code for subscribing to this event is the following:
CarouselHolderComponent`typescript
import { SlidesOutputData, OwlOptions } from 'ngx-owl-carousel-o';
@Component({
selector: '....',
template: ,
})
export class CarouselHolderComponent {
customOptions: OwlOptions = {
loop: true,
mouseDrag: false,
touchDrag: false,
pullDrag: false,
dots: false,
navSpeed: 700,
navText: ['', ''],
responsive: {
0: {
items: 1,
},
400: {
items: 2,
},
740: {
items: 3,
},
940: {
items: 4,
},
},
nav: true,
}; activeSlides: SlidesOutputData;
slidesStore: any[];
constructor() {}
getData(data: SlidesOutputData) {
this.activeSlides = data;
console.log(this.activeSlides);
}
}
`(changed)="getData($event)" is the subscription or attaching to the event;getData(data: SlidesOutputData) is the method which takes data about active slides.activeSlides is the property of CarouselHolderComponent, which stores data about active slidesPlugins
ngx-owl-carousel-o has almost all plugins written on the page
Owl Carousel Plugin API except the VideoPlugin.
$3
This plugin isn't realized. In order to play the video, use special packages (e.g.
ngx-embed-video and so on).It's better to create special component with the video and put it in The example:
`html`
id and url are data-binding properties, defined in the component which contains .
Some examples of using this lib are displayed in the app demo-owl-carousel:
- The carousel with autoWidth=true.autoHeight=true
Typescript part and
HTML part
- The carousel with , URLhashListener=true and startPosition='URLHash'.autoplay=true
Typescript part
and HTML part
- The carousel with .
Typescript part and
HTML part
NOTE: demo-owl-carousel could be downloaded and started on own PC. Steps for achieving that are:
- git clone https://github.com/vitalii-andriiovskyi/ngx-owl-carousel-o.git;yarn
- or npm install;ng serve
- or ng serve --project=demo-owl-carousel.
Also, lots of variants of using carousel are in files
carousel.component.spec.ts
and
stage.component.spec.ts.
They contain tests of the library. These tests include many functions it(). The example:
`typescript
it('should change height of carousel [options]="{nav: true, autoHeight: true}"', fakeAsync(() => {
discardPeriodicTasks();
const html =
Slide 1
Slide 2
Slide 3
Slide 4
Slide 5
;
fixtureHost = createTestComponent(html);
deCarouselComponent = fixtureHost.debugElement.query(By.css('owl-carousel-o'));
tick();
fixtureHost.detectChanges();
// some code ...
}));
`The first argument of
it() explains how the carousel should work with options written in const html=.... In this example the height of the carousel should
change automatically: should change height of carousel [options]="{nav: true, autoHeight: true}".Variable
html contains the HTML-markup of the carousel for [options]="{nav: true, autoHeight: true}".However, most of the HTML-markups set to
html are simplified. There's no property customOptions, directive *ngFor and as it is in
examples above.$3
It's possible to move the carousel left/right and to needed slide from different places of the html-page. The real is provided in
home.component.html
`html
`Key points are:
1. Defining in
template reference variable #owlCar.
2. Using it in handlers for events. In the code above, we see (click)="owlCar.prev()", (click)="owlCar.next()" and (click)="owlCar.to('slide-3')".
#owlCar could be passed as an argument of the hanlder: (click)="handler(owlCar).
- owlCar.prev() shows the previous slide.
- owlCar.next() shows the next slide.
- owlCar.to('slide-3') moves the carousel to the slide with needed id. In this case slide-3 is the needed slide. NOTE: it's needed to supply own
ids to slides. The code above has [id]="item.id". This is the way of supplying ids.ReferenceError: Event is not defined
The details of the issue are following:
`text
$ yarn serve:ssr
yarn run v1.17.3
$ node dist/server
D:\WEB-learning\Angular\projects-libs\owl-carousel\owl-carousel-test-for-built-lib\test-project\owl-carousel-o-demo-ng8\dist\ser
ver\main.js:87252
Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__metadata"])("design:paramtypes", [Event]),
^ReferenceError: Event is not defined
at Module.KMir (D:\WEB-learning\Angular\projects-libs\owl-carousel\owl-carousel-test-for-built-lib\test-project\owl-carousel
-o-demo-ng8\dist\server\main.js:87252:84)
at __webpack_require__ (D:\WEB-learning\Angular\projects-libs\owl-carousel\owl-carousel-test-for-built-lib\test-project\owl-
carousel-o-demo-ng8\dist\server\main.js:20:30)
at Object.F+o+ (D:\WEB-learning\Angular\projects-libs\owl-carousel\owl-carousel-test-for-built-lib\test-project\owl-carousel
-o-demo-ng8\dist\server\main.js:79718:12)
at __webpack_require__ (D:\WEB-learning\Angular\projects-libs\owl-carousel\owl-carousel-test-for-built-lib\test-project\owl-
carousel-o-demo-ng8\dist\server\main.js:20:30)
at Object.V7fC (D:\WEB-learning\Angular\projects-libs\owl-carousel\owl-carousel-test-for-built-lib\test-project\owl-carousel
-o-demo-ng8\dist\server\main.js:99395:12)
at __webpack_require__ (D:\WEB-learning\Angular\projects-libs\owl-carousel\owl-carousel-test-for-built-lib\test-project\owl-
carousel-o-demo-ng8\dist\server\main.js:20:30)
at Object.K011 (D:\WEB-learning\Angular\projects-libs\owl-carousel\owl-carousel-test-for-built-lib\test-project\owl-carousel
demo-ng8\dist\server\main.js:92:18) at __webpack_require__ (D:\WEB-learning\Angular\projects-libs\owl-carousel\owl-carousel-test-for-built-lib\test-project\owl-
carousel-o-demo-ng8\dist\server\main.js:20:30)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
`The issue
`text
Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__metadata"])("design:paramtypes", [Event]),
^ReferenceError: Event is not defined
`is connected with decorator
@HostListener. In the case of ngx-owl-carousel-o, it emerges just in Angular 8.$3
server.ts:`typescript
import * as express from 'express';
import { join } from 'path';// -----------------------------------------------------------------------------------
import { readFileSync } from 'fs'; // import readFileSync (1)
const domino = require('domino'); // import the library
domino (2)
// -----------------------------------------------------------------------------------const app = express();
const PORT = process.env.PORT || 4000;
const DIST_FOLDER = join(process.cwd(), 'dist/browser');
// -----------------------------------------------------------------------------------
const template = readFileSync(join(DIST_FOLDER, 'index.html')).toString(); // use
index.html as template (3)
const win = domino.createWindow(template); // create object Window (4)
global['Event'] = win.Event; // assign the win.Event to prop Event (5)
// -----------------------------------------------------------------------------------// * NOTE :: leave this as require() since this file is built Dynamically from webpack
const { AppServerModuleNgFactory, LAZY_MODULE_MAP, ngExpressEngine, provideModuleMap } = require('./dist/server/main');
`This solution is taken from
https://github.com/hippee-lee/3940-v8-ssr/blob/master/server.ts#L29
$3
server/app.module.ts`typescript
const BROWSER_DIR = join(process.cwd(), 'dist/browser');
applyDomino(global, join(BROWSER_DIR, 'index.html'));
global['Event'] = global['window']['Event']; // define the global property Event
``This project is licensed under the terms of the MIT License