Angular SSR - 无法读取未定义的属性(读取 'unsubscribe')
Angular SSR - Cannot read properties of undefined (reading 'unsubscribe')
我只是为了 SEO 目的将我的 angular 网络应用程序转换为 ssr。我成功地纠正了主要问题,但最后一个我不知道如何处理。
我有一项服务 sqs.service.ts
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();
}
}
每次刷新我的应用程序页面时,我都会收到错误
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.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.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,它工作得很好。问题的原因是什么?提前致谢。
ngOnDestroy
在 Angular 销毁 directive/component 之前进行清理。取消订阅可观察对象并分离事件处理程序以避免内存泄漏。
在 Angular 销毁 directive/component 之前调用。
从你的代码中我无法判断什么是取消订阅,也许你正在全局取消订阅,如果有时在 SSR 中是这种情况,你也必须告诉 angular 它的平台浏览器,因为你可能正在取消订阅某些服务使用 localStorage 或 cookies 等。当你遇到这样的问题时,我也推荐使用它。
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();
}
}
在某些其他情况下,如果您使用某些插件等,则必须在 server.ts 处声明它们,例如:
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);
...
}
我只是为了 SEO 目的将我的 angular 网络应用程序转换为 ssr。我成功地纠正了主要问题,但最后一个我不知道如何处理。
我有一项服务 sqs.service.ts
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();
}
}
每次刷新我的应用程序页面时,我都会收到错误
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.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.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,它工作得很好。问题的原因是什么?提前致谢。
ngOnDestroy
在 Angular 销毁 directive/component 之前进行清理。取消订阅可观察对象并分离事件处理程序以避免内存泄漏。
在 Angular 销毁 directive/component 之前调用。
从你的代码中我无法判断什么是取消订阅,也许你正在全局取消订阅,如果有时在 SSR 中是这种情况,你也必须告诉 angular 它的平台浏览器,因为你可能正在取消订阅某些服务使用 localStorage 或 cookies 等。当你遇到这样的问题时,我也推荐使用它。
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();
}
}
在某些其他情况下,如果您使用某些插件等,则必须在 server.ts 处声明它们,例如:
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);
...
}