代码之家  ›  专栏  ›  技术社区  ›  Teddy Kossoko

角度SSR-无法读取未定义的属性(读取“unsubscribe”)

  •  0
  • Teddy Kossoko  · 技术社区  · 4 年前

    我只是将我的angular web应用程序转换为ssr,用于SEO目的。我成功地纠正了主要问题,但最后一个问题我不知道如何处理。

    我有服务 sqs.service.ts 和尸体一起

    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();
      }
    
    }
    

    每次我刷新应用程序的页面时,都会出现错误

    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
    

    当我删除或注释下面的代码时,我可以成功地重新加载页面,

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

    但我把这个新错误的代码写进去了

    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)
    

    请问我该怎么纠正呢? 虽然没有ssr,但它工作得很好。问题的原因是什么?提前谢谢。

    1 回复  |  直到 4 年前
        1
  •  0
  •   Kevin Dias    4 年前

    恩格德斯特罗

    在Angular销毁指令/组件之前进行清理。取消订阅可观察对象并分离事件处理程序以避免内存泄漏。

    在Angular销毁指令/组件之前调用。

    从你的代码中,我看不出你在取消订阅什么,也许你是在全球范围内取消订阅,如果在SSR中有时出现这种情况,你也必须告诉它的plataform浏览器,因为你可能正在取消订阅一些使用本地存储或cookie等的服务。我也建议你在遇到这样的问题时使用它。

    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();
       }
      }
    

    在其他一些情况下,如果你正在使用一些插件,你必须在服务器上声明它们。ts ex:

    服务器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);
    ...
    
    }