Strange behavior with module.exports and async in React - node.js

Here's a very strange issue that has me puzzled. After creating a React app with create-react-app, I added these two files:
TestMod.js
const TestMod = {
doSomething() {
}
};
module.exports = TestMod;
Test.js
import React, { Component } from 'react';
import TestMod from './TestMod';
export default class Test extends Component {
render() {
TestMod.doSomething();
return <div>Testing</div>;
}
}
I included the Test component inside App, run npm start, and everything worked fine. Then I changed doSomething to be async, like this
TestMod.js
const TestMod = {
async doSomething() {
}
};
module.exports = TestMod;
Now I get a compilation error:
[1] ./src/Test.js
[1] 26:6-13 "export 'default' (imported as 'TestMod') was not found in './TestMod'
Why? I know how to make it work again:
TestMod.js
export const TestMod = {
async doSomething() {
}
};
Test.js
import React, { Component } from 'react';
import {TestMod} from './TestMod';
export default class Test extends Component {
render() {
TestMod.doSomething();
return <div>Testing</div>;
}
}
But what I'd like to understand is why making a function async causes module.exports to break on the React side. (By the way, it still works fine on the Node.js side).
Thanks,
Alvaro

Related

pdfjs throws a TypeError, losing hair

import React, { Component } from "react";
import pdfjs from "pdfjs-dist";
import pdfjsWorker from "pdfjs-dist/build/pdf.worker.entry";
class PdfLoader extends Component {
state = {
pdfDocument: null
};
componentDidMount() {
const { url } = this.props;
pdfjs
.getDocument({ url: url, eventBusDispatchToDOM: true })
.promise.then(pdfDocument => {
this.setState({
pdfDocument: pdfDocument
});
});
}
}
This builds fine under yarn, but at run time, pdfjs.getDocument (ok, minimized, something like co.a.getDocument) throws a TypeError saying it can't handle getDocument of undefined. My other source files and the console show that I am loading my pdf.worker..worker.js file.
I inherited this code from a former co-worker and a previous build on his machine worked, but on mine it always throws this error.

NestJS testing with Jest custom repository (CassandraDB)

The code I am trying to test the driver / repository for my nodeJS project:
import { Injectable, OnModuleInit } from '#nestjs/common';
import { mapping, types } from 'cassandra-driver';
import { Products } from './poducts.model';
import { CassandraService } from '../database/cassandra/cassandra.service';
import Uuid = types.Uuid;
#Injectable()
export class ProductsRepository implements OnModuleInit {
constructor(private cassandraService: CassandraService) {}
productsMapper: mapping.ModelMapper<Products>;
onModuleInit() {
const mappingOptions: mapping.MappingOptions = {
models: {
Products: {
tables: ['products'],
mappings: new mapping.UnderscoreCqlToCamelCaseMappings(),
},
},
};
this.productsMapper = this.cassandraService
.createMapper(mappingOptions)
.forModel('Products');
}
async getProducts() {
return (await this.productsMapper.findAll()).toArray(); // <-----Breaks here with findAll()
}
}
I am trying to write something like this:
describe('product repository get all', () => {
it('calls the repository get all', async () => {
const await productsRepository.getProducts();
expect().DoSomething()
});
});
This is the error I am getting:
Cannot read property 'findAll' of undefined
How would I accomplish a meaning-full test with Jest to get proper code coverage?
When I try to use jest to spy on the this.products.Mapper.findAll() it seems to break every time.

How to test react-native methods?

I want to test Vibration module of react-native, the problem is that I get an error when I try to test it:
With this component:
import React, { useEffect } from 'react';
import { Text, Vibration } from 'react-native';
interface Props {}
export const MyComponent = (props: Props) => {
useEffect(() => Vibration.vibrate(1), []);
return (
<Text>asdaf</Text>
);
};
And this test file:
// #ts-nocheck
import React from 'react';
import { render } from '#testing-library/react-native';
import { NativeModules } from 'react-native';
import { MyComponent } from '../../../src/modules/MyComponent';
describe('MyComponent', () => {
it('alpha', () => {
const { debug } = render(<MyComponent/>);
expect(true).toBeTruthy();
});
});
I get this error:
Invariant Violation: TurboModuleRegistry.getEnforcing(...): 'Vibration' could not be found. Verify that a module by this name is registered in the native binary.
I tried to mock react-native like this:
// #ts-nocheck
import React from 'react';
import { render } from '#testing-library/react-native';
import { NativeModules } from 'react-native';
import { ChatRoomContainer } from '../../../src/modules/ChatRoom';
// Mock NativeModules
jest.mock('react-native', () => ({
...jest.requireActual('react-native'),
Vibration: {
vibrate: jest.fn()
},
__esModule: true
}));
describe('MyComponent', () => {
it('alpha', () => {
const { debug } = render(<ChatRoomContainer/>);
expect(true).toBeTruthy();
});
});
But then I get a ton of warnings related to old modules that should no longer be used:
Warning: CheckBox has been extracted from react-native core and will be removed in a future release. It can now be installed and imported from '#react-native-community/checkbox' instead of 'react-native'. See https://github.com/react-native-community/react-native-checkbox
Warning: DatePickerIOS has been merged with DatePickerAndroid and will be removed in a future release. It can now be installed and imported from '#react-native-community/datetimepicker' instead of 'react-native'. See https://github.com/react-native-community/datetimepicker
What is the best way to test such functionality (like Vibration) of react-native then?
Thanks in advance for you time!
You can mock react-native using the library path, like this:
const mockedVibrate = jest.fn();
jest.mock('react-native/Libraries/Vibration/Vibration', () => ({
vibrate: mockedVibrate,
}));

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

React redux-saga on server side doesn't take action after browser reload

I have some problems with my universal react app runing with saga. I'm rendering react on server. One of my react component executes redux action that should be catched by saga listener on server.
Here is abstract example
// *Header.js*
class Header extends React.PureComponent {
componentWillMount() {
this.props.doAction()
}
....
}
export default connect(null, {doAction})(Header)
// *actions.js*
function doAction() {
return {
type: "action"
}
}
// *saga.js*
function* doAsyncAction(action) {
console.log(action);
}
function* watchAction() {
yield takeEvery("action", doAsyncAction);
}
export default [
watchAction(),
];
// *sagas.js* --> root saga
import 'regenerator-runtime/runtime';
import saga from './saga';
import anotherSaga from './anotherSaga'
export default function* rootSaga() {
yield all([].concat(saga).concat(anotherSaga));
}
// *configureStore.js*
const sagaMiddleware = createSagaMiddleware();
const middleware = applyMiddleware(sagaMiddleware);
...
sagaMiddleware.run(require('./sagas').default);
And after first run node process - it runs and give me console log, but
when I just refresh browser and function doAsyncAction is never executed
Please help, what I'm doing wrong ?
You need to change this:
function doAction() {
return {
type: "action"
}
}
to this:
const mapDispatchtoProps = (dispatch) => {
return {
doAction: () => dispatch({type: "action"})
}
}
export default connect(null, mapDispatchtoProps)(Header)
Client.js setup below for saga middleware:
const sagaMiddleware = createSagaMiddleware()
const createStoreWithMiddleware = applyMiddleware(sagaMiddleware)(createStore)
let store = createStoreWithMiddleware(rootReducers)
sagaMiddleware.run(rootSaga)
The above is implemented where ever you are implementing your store.

Resources