Omit the element that disrupts the functionality of Angular Universal

Utilizing ng-toolkit in conjunction with ng add @ng-toolkit/universal proved to successfully integrate Angular Universal support into my project.

After building the production version without encountering any errors and running the server seamlessly, I faced an issue where the server would not respond when a request was made (nodeJS failed to render any output).

Upon investigation, it was revealed that one of my components was causing this breakdown in server-side rendering. The culprit turned out to be 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>

Is there a way to resolve this issue? Can I exclude a specific component from the Server-Side build in some manner?

Answer №1

If you're looking to solve a common issue, consider utilizing the PLATFORM_ID token along with either the isPlatformBrowser or isPlatformServer method.

Implement the conditional statement in your template using #ngIf:

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

In the component code, set up the isBrowser field as follows:

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) { }
}

To delve deeper into the usage of isPlatformServer and isPlatformBrowser, refer to this informative article where they are employed:

You can also watch my presentation on Angular Universal (starting at 13:26 - covering execution of different code on browser versus server): https://www.youtube.com/watch?v=J42mqpVsg0k

Answer №2

To simplify the process, you can implement a directive similar to this one:

import { isPlatformServer } from '@angular/common';
import { Directive, Inject, OnInit, PLATFORM_ID, TemplateRef, ViewContainerRef } from '@angular/core';

@Directive({ selector: '[ssrExclude]' })
export class SSRExcludeDirective implements OnInit {
    constructor(
        private readonly _viewContainer: ViewContainerRef,
        private readonly _templateRef: TemplateRef<any>,
        @Inject(PLATFORM_ID) private readonly _platformId: Object
    ) { }

    ngOnInit(): void {
        if (isPlatformServer(this._platformId)) {
            this._viewContainer.clear();
        } else {
            this._viewContainer.createEmbeddedView(this._templateRef);
        }
    }
}

After defining the directive above, you can use it in the following manner:

<section *ssrExclude>
    YOUR_HTML_CONTENT_HERE
</section>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Executing event sending from child to parent via ngx-translate

I have been working on creating a multilingual website in Angular using ngx-translate. I store language translations in JSON files located at assets/i18n/en.json (for English) and assets/i18n/ge.json (for German). To handle communication from child to pare ...

Error in Typescript: Cannot assign type 'string[]' to type 'string'

I'm currently developing a project using Next.js with Typescript and .tsx files, and I'm utilizing Supabase as my database. While everything is functioning perfectly on localhost, I'm encountering an issue when trying to build the project o ...

React-leaflet with TypeScript is failing to display GeoJSON Points on the map

I am attempting to display points on a map using geojson points in my react application with react-leaflet. However, for some unknown reason, the points are not rendering on the map. When I try importing a JSON file, I encounter an error: TS2322: Ty ...

What is the reason for TypeScript not displaying a type mismatch error in this particular instance?

After starting to use React with TypeScript, I defined my types as follows: type CardInfo = { cardIndex: null | number; title: string; note: string; _id: string; from: string; cardId: string; }; type ContentType = { title: string; note: st ...

What is the best way to make one element's click event toggle the visibility of another element in Angular 4?

Recently diving into Angular, I'm working on a feature where users can toggle the visibility of a row of details by simply clicking on the item row. The scenario involves a table displaying log entries, each with a hidden row underneath containing spe ...

Changing the font family for a single element in Next.js

One unique aspect of my project is its global font, however there is one element that randomly pulls font families from a hosted URL. For example: https://*****.com/file/fonts/Parnian.ttf My page operates as a client-side rendered application (CSR). So, ...

Angular 4 encounters a hiccup when a mistake in the XHR request brings a halt to a

In my Angular 4 application, I have implemented an observable that monitors an input field. When it detects a URL being entered, it triggers a service to make an XHR request. Observable.fromEvent(this._elementRef.nativeElement, 'input') .debou ...

What is the process of inserting a sparkline chart into a Kendo Angular grid?

I am attempting to display a bullet chart in the first column of my grid. <kendo-grid-column> <ng-template kendoChartSeriesTooltipTemplate let-value="value"> <div> <kendo-sparkline [data]="bulletData" type="bullet" [ ...

Showcasing diverse content with an Angular Dropdown Menu

I'm currently developing an angular application, and I've encountered a difficulty in displaying the user's selection from a dropdown menu. To elaborate, when a user selects a state like Texas, I want to show information such as the period, ...

You are unable to declare an Angular component as an abstract class within a module

In my coding project, there is a fundamental component class known as BaseComponent with its unique markup referred to as <base-component-fun>. The structure of this component's markup looks like this: <div> ..Base markup </div> Thi ...

TypeORM is failing to create a table upon initialization

Recently, I delved into the realm of typescript and decided to explore TypeORM for backend development. My current project involves building a CRUD API using typeORM and postgreSQL. After configuring everything initially, I ran the application only to rea ...

Angular Application caught in an infinite loop

Currently, I have an Angular web application that utilizes the @microsoft/microsoft-graph-client to fetch the logged-in user's details. The user is signed in using @azure/msal-angular. In order to log the user in, I have an authentication service that ...

Material UI React Autocomplete Component

I'm currently working on integrating an Autocomplete component using the Material UI library. However, I've encountered a challenge - I'm unsure of how to properly pass the value and onChange functions, especially since I have a custom Text ...

Angular/NestJS user roles and authentication through JWT tokens

I am encountering difficulties in retrieving the user's role from the JWT token. It seems to be functioning properly for the ID but not for the role. Here is my guard: if (this.jwtService.isTokenExpired() || !this.authService.isAuthenticated()) { ...

Spring Boot fails to recognize path variable data sent from Angular

When working with Angular 7, I encountered a situation where I needed to pass a value from the service class of Angular. Here is how I achieved it: executeHelloWorldBeanServiceWithPathVariable(name){ console.log("name coming from here"+name); retu ...

Upon upgrading @types/angular, I encountered error TS2694 stating that the namespace 'angular' does not have an exported member 'xxx'

Following the upgrade of angular and @types/angular to version 1.6.x, an array of TS2694 errors suddenly appeared: error TS2694: Namespace 'angular' does not include an exported member named 'material' error TS2694: Namespace 'ang ...

Having issues with Angular http.post not sending data when using subscribe

I'm currently facing an issue with sending data to my API using post.subscribe. Despite the fact that no errors are being thrown, the data is not being sent successfully. It's important to note that the API itself is functioning perfectly. Belo ...

Gathering adorned categorizations (sans any listed category divisions)

My current setup involves an event dispatcher class that triggers listeners on specified occurrences. I've successfully implemented registering event listeners via decorators, but I feel like there may be a better solution out there. At the moment, e ...

Type aliases using generics may demonstrate varying behaviors from type aliases without generics

Here is a code snippet to consider: type TestTuple = [ { test: "foo" }, { test: "bar"; other: 1; } ]; type Foo<Prop extends string> = TestTuple extends Record<Prop, string>[] ? true : fal ...

The directive is dynamically altering the disable attribute of its parent element

I am faced with a scenario where I have both a button and a directive in my template. The button can be disabled based on certain parameters defined in the template itself, as well as by the directive (it gets disabled in case of a double click event). B ...