ReferenceError: window is not defined in angular universal - node.js

I am trying to use #nguniversal/express-engine and I have installed and trying to run it but its giving error in main.js file.
This is the error I am getting
C:\Folder\ssr\dist\ssr\server\main.js:179450
})(window, function() {
^
ReferenceError: window is not defined
at Object.rdXg (C:\Folder\ssr\dist\ssr\server\main.js:179450:4)
at __webpack_require__ (C:\Folder\ssr\dist\ssr\server\main.js:26:30)
at Module.+PDj (C:\Folder\ssr\dist\ssr\server\main.js:133:66)
at __webpack_require__ (C:\Folder\ssr\dist\ssr\server\main.js:26:30)
at Module.xCqK (C:\Folder\ssr\dist\ssr\server\main.js:198481:92)
at __webpack_require__ (C:\Folder\ssr\dist\ssr\server\main.js:26:30)
at Module.xLoe (C:\Folder\ssr\dist\ssr\server\main.js:200042:86)
at __webpack_require__ (C:\Folder\ssr\dist\ssr\server\main.js:26:30)
at Module.Mm/0 (C:\Folder\ssr\dist\ssr\server\main.js:89135:105)
at __webpack_require__ (C:\Folder\ssr\dist\ssr\server\main.js:26:30)
A server error has occurred.
node exited with 1 code.
connect ECONNREFUSED 127.0.0.1:59195
I have tried many thing but nothing working.
print function causing the issue and the print function is been used by print-js library
const contentToConvert = document.getElementById('content');
this.selectedFunctionCode = htmlToImage.toPng;
const debugBase64 = this.debugBase64;
this.selectedFunctionCode(contentToConvert)
.then((dataUrl) => {
print(dataUrl, 'image');
})
.catch((error) => {
console.error('oops, something went wrong!', error);
});

because some object like localstorage, window use in client side are not defined in server side you must first check your browser platform is ready then work with these objectes
for this you can do like:
at first generate check-is-browserService.service.ts like this:
export class CheckIsBrowserService {
private isBrowser = new BehaviorSubject<boolean>(null);
constructor() {}
getIsBrowser(): Observable<any> {
return this.isBrowser;
}
setIsBrowser(value: any) {
this.isBrowser.next(value);
}
}
app.component.ts
constructor(
#Inject(PLATFORM_ID) private platformId: any,
private checkIsBrowserService: CheckIsBrowserService
){
this.checkIsBrowserService.setIsBrowser(isPlatformBrowser(platformId));
}
then generate service for example window.service.ts
class Window implements Window {
readonly innerWidth: number;
}
#Injectable({
providedIn: 'root',
})
export class WindowService {
private config: Window;
constructor(private checkIsBrowserService: CheckIsBrowserService) {
this.config = new Window();
this.checkIsBrowserService.getIsBrowser().subscribe((isBrowser) => {
if (isBrowser) {
this.config = window;
}
});
}
innerWidth() {
return this.config.innerWidth;
}
}
and when in your component use window.innerwidth you must change it to
x.component.ts:
constructor(private window: WindowService) {
if (this.window.innerWidth() <= 1024) {
//your code
}
}

Related

Jest testEnvironment: expect is not defined

I'm using Jest 26.x and I defined a custom testEnvironment as so:
import type { EnvironmentContext } from '#jest/environment';
import { Config } from '#jest/types';
import JSDOMEnvironment from 'jest-environment-jsdom';
declare global {
function expectAndMore<ExpectedObject>(
result: ExpectedObject,
expectedObject: ExpectedObject,
): void;
}
class ApprovalTestEnvironment extends JSDOMEnvironment {
constructor(config: Config.ProjectConfig, context: EnvironmentContext) {
super(config, context);
}
async setup() {
await super.setup();
this.global.expectAndMore = ({ result, expectedObject }) => {
expect(result).toEqual(expectedObject);
};
}
async teardown() {
await super.teardown();
}
getVmContext() {
return super.getVmContext();
}
}
export default ApprovalTestEnvironment;
I then configured a unit test file with these comments at the header of my file so it would use the custom environment defined above:
/**
* #jest-environment ./src/approvals/approvalTestEnvironment.ts
*/
But whenever I'm trying to access the expectAndMoreFunction defined in my custom environment with globalThis.expectObjectForPostRequest(result, expected);, I get the following error:
ReferenceError: expect is not defined
Does anyone what causes this and how to fix it?
Note: I'm also using ts-jest 27.1.4.

NestJS Error: Error:Cannot find module './'

I encountered a error when using NestJS. The console shows 0 error first and then crahsed with the Error: Cannot find module './'. This is similar to the
Error:Cannot find module '../module_name'.
However, for this one, it shows './'. And I tried to delete the node_module and the dist folder and rerun the npm install that was usually used to solve the similar people.
The full error message is:
[6:32:11 PM] Starting compilation in watch mode...
[6:32:14 PM] Found 0 errors. Watching for file changes.
Error: Cannot find module './'
Require stack:
- C:\Users\Vibrant\Desktop\inventory_demo\dist\client\client.service.js
- C:\Users\Vibrant\Desktop\inventory_demo\dist\client\client.controller.js
- C:\Users\Vibrant\Desktop\inventory_demo\dist\client\client.module.js
- C:\Users\Vibrant\Desktop\inventory_demo\dist\app.module.js
- C:\Users\Vibrant\Desktop\inventory_demo\dist\main.js
at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
at Function.Module._load (node:internal/modules/cjs/loader:778:27)
at Module.require (node:internal/modules/cjs/loader:1005:19)
at require (node:internal/modules/cjs/helpers:102:18)
at Object.<anonymous> (C:\Users\Vibrant\Desktop\inventory_demo\src\client\client.service.ts:3:1)
at Module._compile (node:internal/modules/cjs/loader:1101:14)
The client.service.js:
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ClientService = void 0;
const common_1 = require("#nestjs/common");
const client_1 = require("./");
let ClientService = class ClientService {
async client(clientWhereUniqueInput) {
return client_1.default.client.findUnique({
where: clientWhereUniqueInput,
});
}
async clients(params) {
const { skip, take, cursor, where } = params;
return client_1.default.client.findMany({
skip,
take,
cursor,
where,
});
}
async createClient(data) {
return client_1.default.client.create({ data });
}
async deleteClient(where) {
return client_1.default.client.delete({ where });
}
async getClientByID(id) {
return await client_1.default.client.findUnique({
where: { client_id: Number(id) },
});
}
async updateClient(params) {
const { where, data } = params;
return client_1.default.client.update({ where, data });
}
};
ClientService = __decorate([
(0, common_1.Injectable)()
], ClientService);
exports.ClientService = ClientService;
//# sourceMappingURL=client.service.js.map
I have two ts files has client in the name:
First one is called client.ts which is a prism database client:
import { PrismaClient } from '#prisma/client';
interface CustomNodeJsGlobal extends NodeJS.Global {
prisma: PrismaClient;
}
// Prevent multiple instances of Prisma Client in development
declare const global: CustomNodeJsGlobal;
const prisma = global.prisma || new PrismaClient();
if (process.env.NODE_ENV === 'development') global.prisma = prisma;
export default prisma;
The second one is a model called client, it only imports the basic nestjs modules I think.
The client module.ts
import { Module } from '#nestjs/common';
import { ClientController } from './client.controller';
import { ClientService } from './client.service';
#Module({
controllers: [ClientController],
providers: [ClientService]
})
export class ClientModule {}
The client controller(haven't start it yet):
import { Controller } from '#nestjs/common';
#Controller('client')
export class ClientController {}
and the client service:
import { Injectable } from '#nestjs/common';
import { Client, Prisma } from '#prisma/client';
import prisma from 'src/client';
#Injectable()
export class ClientService {
// The service to return a single client
async client(
clientWhereUniqueInput: Prisma.ClientWhereUniqueInput,
): Promise<Client> {
return prisma.client.findUnique({
where: clientWhereUniqueInput,
});
}
// The service to return a list of clients
async clients(params: {
skip?: number;
take?: number;
cursor?: Prisma.ClientWhereUniqueInput;
where?: Prisma.ClientWhereInput;
}): Promise<Client[]> {
const { skip, take, cursor, where } = params;
return prisma.client.findMany({
skip,
take,
cursor,
where,
});
}
// The service to create a client
async createClient(data: Prisma.ClientCreateInput): Promise<Client> {
return prisma.client.create({ data });
}
// The service to delete a client
async deleteClient(where: Prisma.ClientWhereUniqueInput): Promise<Client> {
return prisma.client.delete({ where });
}
// The service to find an client by id
async getClientByID(id: string) {
return await prisma.client.findUnique({
where: { client_id: Number(id) },
});
}
// The service to update a client
async updateClient(params: {
where: Prisma.ClientWhereUniqueInput;
data: Prisma.ClientUpdateInput;
}): Promise<Client> {
const { where, data } = params;
return prisma.client.update({ where, data });
}
// End of class
}
The problem is I used a model called client.
The solution is to rename it to clients since NestJS itself uses the name client. After the name modification, I will need to delete the whole dist folder and run npm rebuild.

World outside Step Definition - CucumberJs

I am trying to not make connection between world/customworld and step definitions to keep it neutral.
My Hooks
import { Before, setWorldConstructor } from '#cucumber/cucumber';
setWorldConstructor(CustomWorld);
Before(async function (scenario) {
this.init(scenario);
});
Custom World
import { World } from '#cucumber/cucumber';
import { Builder } from 'selenium-webdriver';
export default class extends World {
public driver = null;
constructor(options: any) {
super(options);
}
async init(scenario: any) {
const thisScenario = scenario;
this.driver = await new Builder().forBrowser('chrome').build();
}
}
Browser/chromedriver
import customWorld from './CustomWorld';
export default class driver_functions extends customWorld {
constructor(options: any) {
super(options);
}
async aa() {
await this.driver.navigate().to('https://google.com').then((value) => {console.log(value);});
}
}
I am getting errors like undefined when I call from step
import driver_functions from '../../utils/driver_functions';
import { Given } from '#cucumber/cucumber';
const df = new driver_functions();
Given('Home_Page: I have a simple maths calculator', async function () {
await driver_functions.aa();
});
at /Users/user.current/Projects/JS_Test/cucumber6-ts-starter-master/node_modules/#cucumber/cucumber/src/runtime/parallel/run_worker.ts:22:9
at processTicksAndRejections (node:internal/process/task_queues:96:5)
caused by: TypeError: Cannot destructure property 'attach' of 'undefined' as it is undefined.
at new World (/Users/user.current/Projects/JS_Test/cucumber6-ts-starter-master/node_modules/#cucumber/cucumber/src/support_code_library_builder/world.ts:21:17)
at new default_1 (/Users/user.current/Projects/JS_Test/cucumber6-ts-starter-master/src/utils/CustomWorld.ts:30:5)
at new driver_functions (/Users/user.current/Projects/JS_Test/cucumber6-ts-starter-master/src/utils/driver_functions.ts:36:5)
at Object.<anonymous> (/Users/user.current/Projects/JS_Test/cucumber6-ts-starter-master/src/step_definitions/maths/simple-maths-steps.ts:6:12)
at Module._compile (node:internal/modules/cjs/loader:1097:14)
at Module.m._compile (/Users/user.current/Projects/JS_Test/cucumber6-ts-starter-master/node_modules/ts-node/src/index.ts:1459:23)

NestJS | Passport: TypeError: Cannot read properties of undefined (reading 'logIn')

Situation:
Developing api in nest & grapqhql
Worked on one laptop, everything was working well
Then cloned my repo on other laptops, installed dependencies, created a new local database.
App is being built with no errors
When following localhost:4000 in browser to open graphql playground I'm receiving 500 error end next message:
ERROR [ExceptionsHandler] Cannot read properties of undefined (reading 'logIn')
TypeError: Cannot read properties of undefined (reading 'logIn')
at authenticate (/home/gleb/Projects/artwine-api/node_modules/passport/lib/middleware/authenticate.js:96:21)
at /home/gleb/Projects/artwine-api/node_modules/#nestjs/passport/dist/auth.guard.js:91:3
at new Promise (<anonymous>)
at /home/gleb/Projects/artwine-api/node_modules/#nestjs/passport/dist/auth.guard.js:83:83
at JWTAccessAuthGuard.<anonymous> (/home/gleb/Projects/artwine-api/node_modules/#nestjs/passport/dist/auth.guard.js:49:36)
at Generator.next (<anonymous>)
at fulfilled (/home/gleb/Projects/artwine-api/node_modules/#nestjs/passport/dist/auth.guard.js:17:58)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
Code of a passport lib function where the error is caught:
return function authenticate(req, res, next) {
req.login =
req.logIn = req.logIn || IncomingMessageExt.logIn;
req.logout =
req.logOut = req.logOut || IncomingMessageExt.logOut;
req.isAuthenticated = req.isAuthenticated || IncomingMessageExt.isAuthenticated;
req.isUnauthenticated = req.isUnauthenticated || IncomingMessageExt.isUnauthenticated;
req._sessionManager = passport._sm;
..............
Link to the repo: https://github.com/Gleb-Gaiduk/artwine-api
Any ideas on what could go wrong after cloning the working repository?
You need to transform the ExecutionContext from Graphql to one Nestjs/Passport can read: https://docs.nestjs.com/graphql/other-features#execution-context
import { ExecutionContext, Injectable } from '#nestjs/common';
import { GqlExecutionContext } from '#nestjs/graphql';
import { AuthGuard } from '#nestjs/passport';
#Injectable()
export class MySuperGuard extends AuthGuard('jwt') {
getRequest(context: ExecutionContext) {
const ctx = GqlExecutionContext.create(context);
return ctx.getContext().req;
}
}
try adding this into "subscriptions" section of GraphQL module initialization:
'subscriptions-transport-ws': {
onConnect: (headersRaw: Record<string, unknown>) => {
// Lowercase each header key
const headers = Object.keys(headersRaw).reduce((dest, key) => {
dest[key.toLowerCase()] = headersRaw[key];
return dest;
}, {});
return {
req: {
headers: headers,
},
};
},
},
I have no idea why it is not documented, but it worked for me.
You should look your Guard and strategy you are using and should handle errors from there for example:
#Injectable()
export class PassportLocalGuard extends AuthGuard('local') {
protected readonly logger = new Logger(PassportLocalGuard.name);
canActivate(context: ExecutionContext) {
const ctx = GqlExecutionContext.create(context);
const { req } = ctx.getContext();
return super.canActivate(new ExecutionContextHost([req]));
}
handleRequest(err: any, user: any) {
if (err) {
this.logger.error(`Auth Error! ${err.message}`);
throw err;
}
if (!user) {
this.logger.error('Auth Error! User not found');
throw new AuthenticationError('Auth Error! User not found');
}
return user;
}
}

ReferenceError: window is not defined Angular Universal

I'm using Angular 10 and trying to implement SSR in my project.
When I run the npm run serve:ssr I'm getting the below error
ReferenceError: window is not defined
When I googled, they suggested to add domino
So below is my server.ts
....
const scripts = fs.readFileSync('dist/asfc-web/browser/index.html').toString();
const window = domino.createWindow(scripts);
global['window'] = window;
global['document'] = window.document;
....
still getting the same error, Please guide me how to resolve this issue.
It's simple fix,
I've imported the AppServerModule after the global['window'] and it worked
global['window'] = window;
global['document'] = window.document;
import { AppServerModule } from '../../projects/asfc-web/src/main.server';
you can use Renderer2 listen for this.
import { Renderer2 } from '#angular/core';
constructor(private renderer2: Renderer2) {
...
}
this.renderer2.listen('window', 'load', event => {
this.innerWidth = event.currentTarget.innerWidth;
console.log(this.innerWidth);
});
You can create new service
import {Injectable} from '#angular/core';
function _window(): any {
return window;
}
#Injectable({
providedIn: 'root'
})
export class WindowRef {
get nativeWindow(): any {
return _window();
}
}
add in constructor where you want to use:
constructor(
private windowRef: WindowRef
) {
}
and use like this:
this.windowRef.nativeWindow.scrollTo({
top: 0,
behavior: 'smooth'
});
or you can check platform:
constructor(
#Inject(PLATFORM_ID) private platformId: any,
private windowRef: WindowRef
) {
}
if (isPlatformBrowser(this.platformId)) {
this.windowRef.nativeWindow.scrollTo({
top: 0,
behavior: 'smooth'
});
}

Resources