Home > Software design >  Angular SSR - Cannot read properties of undefined (reading 'unsubscribe')
Angular SSR - Cannot read properties of undefined (reading 'unsubscribe')

Time:04-04

I just convert my angular web app to ssr for SEO purposes. I succeeded to correct main issues, but this last one i don't know how to deal with.

I have a service sqs.service.ts with the body

import { Injectable, OnInit } from '@angular/core';
import { CookieService } from 'ngx-cookie-service';
import { Router } from '@angular/router';
import {SNSClient, PublishCommand, MessageAttributeValue} from "@aws-sdk/client-sns";

import { interval, Subscription } from 'rxjs';
import { CognitoIdentityClient } from "@aws-sdk/client-cognito-identity";
import { fromCognitoIdentityPool }  from "@aws-sdk/credential-provider-cognito-identity";
import {environment} from "../../../../../../environments/environment";
import {AuthService} from "../../../../../modules/auth";


export interface SnsNotificationMessage {
  Message: string;
  TopicArn: string;
  MessageAttributes: { [key: string]: MessageAttributeValue; }
}

@Injectable({ providedIn: 'root' })
export class SqsService {

  // Set the AWS Region
  REGION = "eu-west-3";
  subscription: Subscription;
  // Set the parameters
  mnotificationTopicArn = environment.MNOTIFICATION_TOPIC_ARN;



  constructor(
    private cookieService: CookieService,
    private router: Router,
    private authentService: AuthService,
  ) {


  }




  ngOnDestroy() {
    this.subscription.unsubscribe();
  }


  /**
   * Send notification to mnotification
   * @param params
   */
  sendNotification(params: SnsNotificationMessage) {

    const idToken = this.cookieService.get(this.authentService.GARA_WEB_USER_JWT_ID_TOKEN_COOKIE);
    // create sns client
    const snsClient = new SNSClient({
      region: this.REGION,
      credentials: fromCognitoIdentityPool({
        client: new CognitoIdentityClient({region: this.REGION}),
        identityPoolId: environment.identityPoolId,
        logins: {
          [environment.cognitoPoolId]: idToken   // 'COGNITO_ID' has the format 'cognito-idp.REGION.amazonaws.com/COGNITO_USER_POOL_ID'
        },
      })
    });

    const run = async () => {
      try {
        const data = await snsClient.send(new PublishCommand(params));
        console.log("Success.",  data);
        return data; // For unit tests.
      } catch (err) {
        console.log("Error", err.stack);
      }
    };
    run();
  }

}

Each time i refresh a page of my app, I got the error

TypeError: Cannot read properties of undefined (reading 'unsubscribe')
    at SqsService.ngOnDestroy (C:\Users\koste\OneDrive\Documents\Gara\front end\gara-web\dist\gara-app\server\27.js:49:23)
    at C:\Users\koste\OneDrive\Documents\Gara\front end\gara-web\dist\gara-app\server\main.js:58964:55
    at Set.forEach (<anonymous>)
    at R3Injector.destroy (C:\Users\koste\OneDrive\Documents\Gara\front end\gara-web\dist\gara-app\server\main.js:58964:28)
    at NgModuleRef$1.destroy (C:\Users\koste\OneDrive\Documents\Gara\front end\gara-web\dist\gara-app\server\main.js:73080:41)
    at C:\Users\koste\OneDrive\Documents\Gara\front end\gara-web\dist\gara-app\server\main.js:77106:56
    at Array.forEach (<anonymous>)
    at PlatformRef.destroy (C:\Users\koste\OneDrive\Documents\Gara\front end\gara-web\dist\gara-app\server\main.js:77106:31)
    at complete (C:\Users\koste\OneDrive\Documents\Gara\front end\gara-web\dist\gara-app\server\main.js:93213:26)
    at C:\Users\koste\OneDrive\Documents\Gara\front end\gara-web\dist\gara-app\server\main.js:93217:24

When i remove or comment the code hereinafter, i can succeed to to reload a page,

  ngOnDestroy() {
    //this.subscription.unsubscribe();
  }

but i got in the code this new error

ERROR NetworkError
    at XMLHttpRequest.send (C:\Users\koste\OneDrive\Documents\Gara\front end\gara-web\dist\gara-app\server\main.js:521132:19)
    at Observable._subscribe (C:\Users\koste\OneDrive\Documents\Gara\front end\gara-web\dist\gara-app\server\main.js:13619:17)
    at Observable._trySubscribe (C:\Users\koste\OneDrive\Documents\Gara\front end\gara-web\dist\gara-app\server\main.js:504773:25)
    at Observable.subscribe (C:\Users\koste\OneDrive\Documents\Gara\front end\gara-web\dist\gara-app\server\main.js:504759:22)
    at scheduleTask (C:\Users\koste\OneDrive\Documents\Gara\front end\gara-web\dist\gara-app\server\main.js:92458:32)
    at Observable._subscribe (C:\Users\koste\OneDrive\Documents\Gara\front end\gara-web\dist\gara-app\server\main.js:92496:13)
    at Observable._trySubscribe (C:\Users\koste\OneDrive\Documents\Gara\front end\gara-web\dist\gara-app\server\main.js:504773:25)
    at Observable.subscribe (C:\Users\koste\OneDrive\Documents\Gara\front end\gara-web\dist\gara-app\server\main.js:504759:22)
    at innerSubscribe (C:\Users\koste\OneDrive\Documents\Gara\front end\gara-web\dist\gara-app\server\main.js:505776:23)
    at MergeMapSubscriber._innerSub (C:\Users\koste\OneDrive\Documents\Gara\front end\gara-web\dist\gara-app\server\main.js:510200:98)

Please how could i correct it ? Whithout ssr it is working perfectly. What is the cause of the issue ? Thanks in advance.

CodePudding user response:

ngOnDestroy

Cleanup just before Angular destroys the directive/component. Unsubscribe observables and detach event handlers to avoid memory leaks.

Called just before Angular destroys the directive/component.

From your code i can´t tell what are Unsubscribing maybe you are Unsubscribing globally, if that the case sometimes in SSR you have too tell angular its plataform browser, because you may being Unsubscribing some services that uses localStorage or cookies ect. I recomend too use it when u have issues like this.

import { PLATFORM_ID } from "@angular/core";
import { isPlatformBrowser } from '@angular/common';

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


ngOnDestroy() {
  if (isPlatformBrowser(this.platformId)) {
    this.subscription.unsubscribe();
   }
  }

and in some other cases if you are using some plugins ect you have to declare them at server.ts ex:

server.ts

function setBrowserGlobals(distFolder) {
  const template = readFileSync(join(distFolder, 'index.html')).toString();
  const domino = require('domino');
  const win = domino.createWindow(template);
  global['window'] = win;
 // custom plugin cookieconsent
  global['window']['cookieconsent'] = {
    initialise: function () {
      //
    }
  };
}

export function app(): express.Express {
 const server = express();
  const distFolder = join(process.cwd(), 'dist/browser');
  const indexHtml = existsSync(join(distFolder, 'index.original.html')) ? 'index.original.html' : 'index';
  setBrowserGlobals(distFolder);
...

}
  • Related