Carousel is not working with Angular Universal


Topic: Carousel is not working with Angular Universal

Gaurav Garg pro asked 7 years ago

Hi Team, I am trying to run Carousel on one page. Below is the code. If i remove this code from component then the page is loading in universal build. But if i add below code in component then universal build is not working. But same code is working in dev mode. In universal build, i have added hammerjs in whitelist. let me send you universal configuration also. ----------HTML Code  Starts ------------------------------ <!--Carousel Wrapper--> <mdb-carousel [isControls]="true" [animation]="'slide'"> <!--First slide--> <mdb-slide> <imgclass="d-block w-100"src="https://mdbootstrap.com/img/Photos/Slides/img%20(130).jpg"alt="First slide"> </mdb-slide> <!--/First slide--> <!--Second slide--> <mdb-slide> <imgclass="d-block w-100"src="https://mdbootstrap.com/img/Photos/Slides/img%20(129).jpg"alt="Second slide"> </mdb-slide> <!--/Second slide--> <!--Third slide--> <mdb-slide> <imgclass="d-block w-100"src="https://mdbootstrap.com/img/Photos/Slides/img%20(70).jpg"alt="Third slide"> </mdb-slide> <!--/Third slide--> </mdb-carousel> <!--/.Carousel Wrapper--> ----------HTML Code  ENDS ------------------------------ --------------- Module code starts ------------------------ const routes: Routes = [ { path: '', component: HotelListComponent} ] @NgModule({ imports: [ CommonModule, RouterModule.forChild(routes), CarouselModule.forRoot(), CoreModule ], declarations: [HotelListComponent], schemas: [NO_ERRORS_SCHEMA], exports: [HotelListComponent] }) export class HotelListModule { } -----------Module code ends ----------------------- --------------webpack starts-------------------------- const path = require('path'); const webpack = require('webpack'); var nodeExternals = require('webpack-node-externals'); module.exports = { entry: { server:'./server.ts' }, resolve: { extensions: ['.js', '.ts'] }, target:'node', // this makes sure we include node_modules and other 3rd party libraries externals: [nodeExternals({ whitelist: [ /^@agm/core/, /^hammerjs/ ] })], output: { path:path.join(__dirname, 'dist'), filename:'[name].js' }, module: { rules: [{ test: /.ts$/, loader:'ts-loader' }] }, plugins: [ // Temporary Fix for issue: https://github.com/angular/angular/issues/11580 // for 'WARNING Critical dependency: the request of a dependency is an expression' newwebpack.ContextReplacementPlugin( /(.+)?angular(\|/)core(.+)?/, path.join(__dirname, 'src'), // location of your src {} // a map of your routes ), newwebpack.ContextReplacementPlugin( /(.+)?express(\|/)(.+)?/, path.join(__dirname, 'src'), {} ) ] }; -------------Webpack ends ---------------------------- --------------Server.ts starts------------------------------ // These are important and needed before anything else import 'zone.js/dist/zone-node'; import 'reflect-metadata'; import { enableProdMode } from '@angular/core'; import * as express from 'express'; import { join } from 'path'; const domino = require('domino'); const fs = require('fs'); const template = fs.readFileSync(join(process.cwd(), 'dist', 'browser', 'index.html')).toString(); console.log("join(process.cwd(), 'dist', 'browser', 'index.html') is ", join(process.cwd(), 'dist', 'browser', 'index.html')) const win = domino.createWindow(template); global['window'] = win; global['document'] = win.document; global['XMLHttpRequest'] = require('xmlhttprequest').XMLHttpRequest; // Faster server renders w/ Prod mode (dev mode never needed) enableProdMode(); // Express server const app = express(); const PORT = process.env.PORT || 4000; const DIST_FOLDER = join(process.cwd(), 'dist'); // * NOTE :: leave this as require() since this file is built Dynamically from webpack const { AppServerModuleNgFactory, LAZY_MODULE_MAP } = require('./dist/server/main.bundle'); // Express Engine import { ngExpressEngine } from '@nguniversal/express-engine'; // Import module map for lazy loading import { provideModuleMap } from '@nguniversal/module-map-ngfactory-loader'; app.engine('html', ngExpressEngine({ bootstrap:AppServerModuleNgFactory, providers: [ provideModuleMap(LAZY_MODULE_MAP) ] })); app.set('view engine', 'html'); app.set('views', join(DIST_FOLDER, 'browser')); // TODO: implement data requests securely app.get('/api/*', (req, res) => { res.status(404).send('data requests are not supported'); }); // Server static files from /browser app.get('*.*', express.static(join(DIST_FOLDER, 'browser'))); // All regular routes use the Universal engine app.get('*', (req, res) => { global['navigator'] =req['headers']['user-agent']; res.render(join(DIST_FOLDER, 'browser', 'index.html'), { req }); }); // Start up the Node server app.listen(PORT, () => { console.log(`Node server listening on http://localhost:${PORT}`); }); -----------------Server.ts ends --------------------------------------

Damian Gemza staff commented 7 years ago

Dear Guarav, do your console or terminal throws you any errors or warnings?

Gaurav Garg pro answered 7 years ago

Hey I found the solution of this issue.  Issue is [interval]="0" this property. If you don't give this property then in dev mode it will work but in universal mode it will not work. I guess you have to document "interval" property somewhere.
<mdb-carousel [isControls]="true" [animation]="'slide'" [interval]="0">
<!--First slide-->
<mdb-slide>
<imgclass="d-block w-100"src="http://www.nyalahotel.com/wp-content/uploads/2015/03/nyala_pool3.jpg"alt="First slide">
</mdb-slide>
<!--/First slide-->
<!--Second slide-->
<mdb-slide>
</mdb-slide>
<!--/Second slide-->
<!--Third slide-->
<mdb-slide>
</mdb-slide>
<!--/Third slide-->
</mdb-carousel>
<!--/.Carousel Wrapper-->

Damian Gemza staff commented 7 years ago

Thanks for your solution! We'll add this to our docs. Best Regards, Damian

Gaurav Garg pro answered 7 years ago

Hi Damian, This is the major concern i am not able to see any error or warning in console. You know tooltip, button, navbar and login components are working perfectly. Only carousel is creating issue.

Gaurav Garg pro answered 7 years ago

Hi Damian, I am not sure if this issue is related to below url. https://github.com/valor-software/ngx-bootstrap/issues/3073

Gaurav Garg pro answered 7 years ago

Hi Damian, I have tried new set up also which is recommended by you guys. But this is also not working with carousel. Please help. https://mdbootstrap.com/angular/angular-universal/  

Damian Gemza staff commented 7 years ago

Dear Guarav, please read about using static images in Universal. Here's some links: http://dev.sebastienlucas.com/how-to-use-the-angular-universal-starter/ https://scotch.io/tutorials/server-side-rendering-in-angular-2-with-angular-universal I'll add this section to our tutorial. Best Regards, Damian

Gaurav Garg pro answered 7 years ago

Hi

I guess i found one more issue in carousel

this code is working with universal because interval is equal to 0.[interval]="0"

<mdb-carousel [interval]="0" [isControls]="true" class="carousel slide carousel-fade" [type]="'carousel-thumbnails'" [animation]="'fade'">
<!--First slide-->
<mdb-slide *ngFor="let image of images">
<imgclass="d-block w-100"src="{{imageBaseURL}}{{image}}"alt="First slide">
</mdb-slide>
</mdb-carousel>

---------------------------------------------------------------------------------------------------------------------------
but this code is not working with universal because i am using variable to initialize interval. May be reason is setInterval method.

public myInterval: number = 3000;

<mdb-carousel [interval]="myInterval" [isControls]="true" class="carousel slide carousel-fade" [type]="'carousel-thumbnails'" [animation]="'fade'">
<!--First slide-->
<mdb-slide *ngFor="let image of images">
<imgclass="d-block w-100"src="{{imageBaseURL}}{{image}}"alt="First slide">
</mdb-slide>
</mdb-carousel>


Gaurav Garg pro answered 7 years ago

Hi Damian, I made some changes in CarouselComponent. Below are my changes and changes are working perfectly on universal. But now i am facing one more issue [type]="'carousel-thumbnails'" is not working in universal code. Please help.
privaterestartTimer():any {
this.resetTimer();
constinterval=+this.interval;
if (!isNaN(interval) &&interval>0) {
this.currentInterval=this.ngZone.runOutsideAngular(() => {
returnsetInterval(() => {
letnInterval=+this.interval;
this.ngZone.run(() => {
if (this.isPlaying&&!isNaN(this.interval) &&nInterval>0&&this.slides.length) {
this.nextSlide();
} else {
this.pause();
}
});
}, interval);
});
}
}
------------------------------------------------------------
In below code, i am using thumbnails and it is not working in universal only. In normal dev environment, it is working.
<mdb-carousel [interval]="slideInterval" [isControls]="true" class="carousel slide carousel-fade" [type]="'carousel-thumbnails'" [animation]="'fade'">
<!--First slide-->
<mdb-slide *ngFor="let image of images">
<imgclass="d-block w-100"src="{{imageBaseURL}}{{image}}"alt="First slide">
</mdb-slide>
</mdb-carousel>

Please insert min. 20 characters.

FREE CONSULTATION

Hire our experts to build a dedicated project. We'll analyze your business requirements, for free.

Status

Answered

Specification of the issue
  • User: Pro
  • Premium support: No
  • Technology: MDB Angular
  • MDB Version: -
  • Device: -
  • Browser: -
  • OS: -
  • Provided sample code: No
  • Provided link: No