Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exclude component that breaks Angular Universal

I used ng-toolkit with ng add @ng-toolkit/universal to add Angular Universal support to my project.

I am able to create the prod build with no errors plus I am able to run the server, again without any errors. It just get "stuck" when request comes to it (nodeJS does not render any output).

I found out, that one of my components is breaking server-side rendering. I found out that the issue is with the Mat-Carousel:

component:

export class BannerComponent {

  slides: any[] = [
    // tslint:disable-next-line:max-line-length
    { image: 'assets/banner/banner-one.png' },
    // tslint:disable-next-line:max-line-length
    { image: 'assets/banner/banner-two.png' },
    // tslint:disable-next-line:max-line-length
    { image: 'assets/banner/banner-three.png' }
  ];

}

template:

<section class="sec-space-b" id="banner">
    <mat-carousel
        timings="250ms ease-in"
        [autoplay]="true"
        interval="5000"
        color="accent"
        maxWidth="auto"
        proportion="25"
        slides="5"
        [loop]="true"
        [hideArrows]="false"
        [hideIndicators]="false"
        [useKeyboard]="true"
        [useMouseWheel]="false"
        orientation="ltr"
      >
        <mat-carousel-slide
            #matCarouselSlide
            *ngFor="let slide of slides; let i = index"
            overlayColor="#00000000"
            [image]="slide.image"
            [hideOverlay]="false"
        ></mat-carousel-slide>
    </mat-carousel>
</section>

How can I solve this problem? Can I somehow exclude particular component from the Server-Side build?

like image 342
Immad Hamid Avatar asked Mar 28 '19 22:03

Immad Hamid


1 Answers

The fix is simple, you should use a PLATFORM_ID token together with the isPlatformBrowser or isPlatformServer method.

Inside your template use the #ngIf statement:

<section class="sec-space-b" id="banner" *ngIf="isBrowser">

And inside the component code initialize the isBrowser field as:

import { isPlatformBrowser } from '@angular/common';
import { Component, OnInit, Inject, PLATFORM_ID } from '@angular/core';


@Component({
  selector: 'app-home-banner',
  templateUrl: './banner.component.html',
  styleUrls: ['./banner.component.scss']
})
export class BannerComponent implements OnInit {

  public isBrowser = isPlatformBrowser(this.platformId);

  constructor(@Inject(PLATFORM_ID) private platformId: any) { }
}

You can read more about isPlatformServer and isPlatformBrowser in this article (they are used there): https://www.twilio.com/blog/create-search-engine-friendly-internationalized-web-apps-angular-universal-ngx-translate

You can also check out my talk about Angular Universal (13:26 - about running different code on browser and server): https://www.youtube.com/watch?v=J42mqpVsg0k

like image 178
Maciej Treder Avatar answered Sep 18 '22 20:09

Maciej Treder