Require vs. import - javascript

Code runs without errors when I require compared to when I import, then I receive an error:
app.js:
// require("#babel/polyfill");
// require("#babel/core");
import babel from '#babel/core';
import babelpoly from '#babel/polyfill';
import axios from 'axios';
const BASE_URL = 'https://jsonplaceholder.typicode.com';
const getTodos = async () => {
try {
const res = await axios.get(`${BASE_URL}/todos`);
const todos = res.data;
console.log(`GET: Here's the list of todos`, todos);
return todos;
} catch (e) {
console.error(e);
}
};
Based on what I understand, require and import have the same functionality but they have performance trade offs. I must be wrong, otherwise it would've worked both ways

import is an ES6 feature and needs babel to convert import to Common JS require. You should require babel to use import.

Related

Critical dependency: the request of a dependency is an expression while using lazy loading

I am trying to dynamically import modules but getting following error -
Compiled with problems:X
WARNING in ./src/.../useCustomModule.js 21:21-56
Critical dependency: the request of a dependency is an expression
import React from "react";
import PropTypes from "prop-types";
export const moduleMapping = {
CONTEXT_ONE: "./....contextOnePath",
CONTEXT_TWO: "./....contextTwoPath",
};
const getModule = (moduleName) => {
const module = React.lazy(() => import(moduleMapping[moduleName]));
return module;
};
export const useCustomModule = (moduleName) => {
return getModule(moduleName);
};
Note : In eslintrc.json I have following settings - "ecmaVersion": 12,
Recently, I also faced a similar issue but when I used string interpolation, the warning went away.
In your code, give a try to this:
const getModule = (moduleName) => {
const module = React.lazy(() => import(`${moduleMapping[moduleName])}`);
return module;
};

How to reach a Context API method inside of a helper function?

I created a file which would contain helper functions for querying the database. My problem is that I have to get my access token through the Context API but I can't call the useContext hook outside of a functional component. I could place the functions inside one, but I don't need the component, it would be unused. What is the best practice here?
import React, { useContext } from "react";
import axios from "axios";
import { AuthContext } from "../../contexts/auth-context.js";
import { mongoQuery } from "../xhr/QueryMongo";
const { getAccessToken } = useContext(AuthContext);
export async function fetchUserData(userId) {
const sRealmApp = "...";
const CancelTokenLogin = axios.CancelToken;
const sourceLogin = CancelTokenLogin.source();
let token = await getAccessToken("users");
const userQuery = `query {user (query:{_id:"${userId}"}) {name, role, residence }}`;
let queryResult = await mongoQuery(token, sRealmApp, userQuery, sourceLogin);
if (queryResult.data.data !== null && queryResult.data.data.user !== null) {
return queryResult.data.data.user;
} else return false;
//other similar helper functions....
}
(Why I'm creating a new file: I'm refactoring my code because I have a file which has 400 lines of code, but it's not a big project. So I decided to extract code which connects to the database because it's not directly linked to the component.)
You can always provide the context as a parameter for your helper function.
helperFunction.js
fetchUserData(userId, token) {
... rest of code
}
Component.js
Then get the token from your component using useContext
import React, {useContext, useEffect} from 'react';
import context from 'location of context';
import fetchUserData from 'location of helper function';
const Component = () => {
const userId = 123; // Not sure where you are getting this, but for example.
const {getToken} = useContext(context);
useEffect(() => {
fetchUserData(userId, getToken());
}, []);
return (JSX)
};
Although, I don't think this is the best approach. I've done this before and it makes testing a nightmare. Creating a customHook would be a better approach imo.

Jest Mocked Function not calling mocked axios instance function (returns undefined)

I started by following the answer in this StackOverflow Question
But I added a helper function I use which creates a new Axios instance with the auth token associated with the user.
Which looks a little like this:
import axios from "axios";
const mockAxios: jest.Mocked<typeof axios> = jest.createMockFromModule("axios");
// this is the key to fix the axios.create() undefined error!
mockAxios.create = jest.fn(() => {
return mockAxios;
});
export const createAuthenticatedInstance = () => {
return mockAxios.create();
};
export default mockAxios;
Why does mockAxios.create() return undefined?
While the object 'mockAxios' (and the create function) is defined. When I actually call create it returns undefined despite the function being declared.
I know that I can side-step the issue by just returning mockAxios against but I'd like to understand why it doesn't work in the first place. What I'd expect is to return a new instance, which would be identical to mockAxios but it just returns undefined.
If you're creating an auto-mock (within __mocks__) it's meant to be a mock of the module and any helper functions are not expected to be within the module, but probably somewhere else with your code
Exmaple:
src/axios.utils.ts (utility module which exports axios and the function)
import axios from "axios";
export const createAuthenticatedInstance = (
...args: Parameters<typeof axios.create>
) => {
return axios.create(...args);
};
export default axios;
src/__mocks__/axios.ts (the axios mock)
const axios: jest.Mocked<typeof import("axios").default> = jest.createMockFromModule(
"axios"
);
axios.create.mockReturnThis();
export default axios;
src/api.ts (api implementation that uses the axios.util)
import axios from "axios";
import { createAuthenticatedInstance } from "./axios.utils";
const client = createAuthenticatedInstance({
baseURL: "http://example.com:80/main",
});
export default {
makeSomeReq: () => client.get<string>("/path"),
};
src/api.spec.ts (the test)
import api from "./api";
import axios, { AxiosResponse } from "axios";
jest.mock("axios");
const { get } = axios as jest.Mocked<typeof import("axios").default>;
describe("api", () => {
it("should have created an axios instance", () => {
expect(axios.create).toHaveBeenCalledWith({
baseURL: "http://example.com:80/main",
});
});
})
working example

Line 105:14: 'accountSelector' is not defined no-undef

Could someone please explain what is going wrong in simple terms so I know how to fix this and can deal with it next time I encounter it.
I have looked through all related questions I could find on stackoverflow and haven't been able to fix it, if I have missed one that answers this then please link it.
I have had this error in the past but usually that was just because I had a typo (e.g. a capital instead of a lowercase) or did not import something correctly however that is not the case this time as far as I can tell.
FIRST CODE app.js
SECOND CODE interactions.js
Here is my code
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import Navbar from './Navbar'
import Web3 from 'web3';
import { connect } from 'react-redux'
// import Token from '../abis/Token.json'
import {
loadWeb3,
loadAccount,
loadToken,
loadExchange
} from '../store/interactions'
class App extends Component {
componentWillMount() {
this.loadBlockchainData(this.props.dispatch)
}
async loadBlockchainData(dispatch) {
const web3 = loadWeb3(dispatch)
const network = await web3.eth.net.getNetworkType()
const networkId = await web3.eth.net.getId()
const accounts = await loadAccount(web3, dispatch) // <<--
const token = loadToken(web3, networkId, dispatch)
loadExchange(web3, networkId, dispatch)
}
// ......................
function mapStateToProps(state) {
return {
account: accountSelector(state)
}
}
export default connect(mapStateToProps)(App);
import Web3 from 'web3'
import {
web3Loaded,
web3AccountLoaded,
tokenLoaded,
exchangeLoaded
} from './actions'
import Token from '../abis/Token.json'
import Exchange from '../abis/Exchange.json'
export const loadWeb3 = (dispatch) => {
const web3 = new Web3(Web3.givenProvider || 'http://localhost:7545')
dispatch(web3Loaded(web3))
return web3
}
export const loadAccount = async (web3, dispatch) => {
const accounts = await web3.eth.getAccounts()
const account = accounts[0]
dispatch(web3AccountLoaded(account))
return account
}
export const loadToken = async (web3, networkId, dispatch) => {
try {
const token = new web3.eth.Contract(Token.abi, Token.networks[networkId].address) // new 이거 의존성(버전) 문제 이거 조심!!!!!
dispatch(tokenLoaded(token))
return token
} catch (error) {
window.alert('Contract not deployed to the current network. Please select another network with Metamask.')
return null
}
}
export const loadExchange = async (web3, networkId, dispatch) => {
try {
const exchange = new web3.eth.Contract(Exchange.abi, Exchange.networks[networkId].address)
dispatch(exchangeLoaded(exchange))
return exchange
} catch (error) {
window.alert('Contract not deployed to the current network. Please select another network with Metamask.')
return null
}
}
i don'k now why this happening to me
but please let me know this problem if you know this issue
The problem seems to be that you do not define or import the accountSelector function anywhere.
You usually define Redux selector functions in your reducer definition files: they take the current Redux store state as argument (and optionally the connected component props) and return the value to be used in your MapStateToProps object property.
Ex.
export const accountSelector = (state) => state.account
You can read more about selectors on the dedicated Redux resources page
replace this
function mapStateToProps(state) {
return {
account: accountSelector(state)
}
}
with this
function mapStateToProps(state) {
return {
account: state.accountSelector
}
}
you are passing complete state in variable instead of accessing.
for your reference, how to access please go through official documentation for your better understanding Redux

Jest spyon works when 'require' mocked module and doesn't work when 'import'

I want to test that my third-party-library (iframe-resizer) function is called.
My test
import React from 'react';
import { fireEvent, render } from 'react-testing-library';
//import * as depModule from 'iframe-resizer';
let depModule = require("iframe-resizer")
import { MyComponent } from '../my-component';
describe('Component', () => {
describe('Functional', () => {
it('should initialize iframeresizer when the iframe has loaded', async
() => {
const iframeResizerMock = jest.spyOn(depModule, "iframeResizer");
const { queryByTestId } = render(<MyComponent />);
fireEvent.load(queryByTestId('csb-iframe'));
expect(iframeResizerMock).toHaveBeenCalledTimes(1);
});
});
});
So the iframeResizer function is called,it was tested by console.log.The strange thing here is when I use
import * as depModule from 'iframe-resizer';
The spyon doesn't work(test fails)
But when I use
let depModule = require("iframe-resizer")
Everything works great(test passes) . I'm new in jest and node modules,so may be I missed simething obvious?
This happens because jest's mocking only works for commonjs modules, and in your case iframe-resizer does not ship commonjs modules, and jest does not transform node modules to commonjs.
Take a look at this thread. There are many interesting solutions in there.

Categories