I'm making an API for a web application, and I'm running into a weird problem when I try to import a module. I have a folder with a bunch of models used to get data from the database, and I have a folder named "global" with various modules used all over the project.
/
/api
/models
/Users.js
/Trainings.js
/TrainingsTypes.js
/TrainingsSubtypes.js
/global
/Functions.js
Some of the models import other models to check ID, get data, etc. I made a function in Functions.js that also needs some of the models to work. So basically, the import dependencies look like:
I must admit, this is a little crappy when showed like that. But here is my problem. As long as Functions.js doesn't import Users.js, everything is fine. The API works well and there's no crash at all. But, if I import Users.js in Functions.js, I immediatly get this error:
ReferenceError: Cannot access 'Users' before initialization
at file:///C:/Users/USERNAME/Desktop/project-api/global/Functions.js:30:10
at ModuleJob.run (internal/modules/esm/module_job.js:169:25)
at async Loader.import (internal/modules/esm/loader.js:177:24)
at async Object.loadESM (internal/process/esm_loader.js:68:5)
Here is the code of Functions.js (I put a comment to indicate line 30):
import check from "checkers";
import Users from "../api/models/Users.js";
import Trainings from "../api/models/Trainings.js";
import TrainingsTypes from "../api/models/TrainingsTypes.js";
import TrainingsSubtypes from "../api/models/TrainingsSubtypes.js";
/*****************************************************
* SQL Queries
*****************************************************/
export function fieldsToUpdate(fields) {...}
const fillers = {
"user": Users, // Line 30
"trainer": Users,
"type": TrainingsTypes,
"subtype": TrainingsSubtypes
};
export async function fillIDs(db, response) {...}
Moreover, the import itself doesn't cause problems. If I remove Users from the fillers object, there's still no crash. I've seen that might be a cyclic dependencies issue but some says that Node can handle this. I must add that I really need all my models in fillIDs() so I just can't remove all the import and I didn't want to copy/paste this code in every model. There must be a solution, but I need some help.
Have you any idea how to fix this?
Thanks
EDIT 1:
Users.js import these modules:
import bcrypt from "bcryptjs";
import generatePwd from "generate-password";
import { v4 as uuidv4 } from "uuid";
import check from "checkers";
import { fieldsToUpdate, fillIDs } from "../../global/Functions.js";
import { arrayToSerialComma } from "../../global/Converters.js";
import APIResp from "../../global/APIResp.js";
import Mailer from "../../global/Mailer.js";
import Genders from "./Genders.js";
import Roles from "./Roles.js";
import Tokens from "./Tokens.js";
import { Passwords } from "../../config/config.js";
EDIT 2:
Users.js is exported in this way:
const Users = {
isValid,
add,
logIn, getAll, getById, getByEmail, hasForgotPassword, getRolesOf,
update, updatePwd, passwordForgotten,
delete: del,
Trainers: {
getById: getTrainerById,
getAll: getAllTrainers
}
};
export default Users;
I managed to partially solve my problem. I've created a file in global exporting all the files in this folder and did the same for models.
// ROOT/global/global.js
export { default as APIResp } from "./APIResp.js";
export { default as SQLFunctions } from "./SQLFunctions.js";
export { default as Mailer } from "./Mailer.js";
export { default as ModuleConsole } from "./ModuleConsole.js";
// ROOT/api/models/models.js
export { default as Users } from "./Users.js";
export { default as Genders } from "./Genders.js";
export { default as Roles } from "./Roles.js";
export { default as Tokens } from "./Tokens.js";
export { default as Trainings } from "./Trainings.js";
export { default as TrainingsTypes } from "./TrainingsTypes.js";
export { default as TrainingsSubtypes } from "./TrainingsSubtypes.js";
I also removed some functions that was needed in both the front-end and back-end and moved them to an external module. I used madge to generate a dependency graph.
As we can see, it's not perfect yet. All the models files are actually in a big circular dependency but it's much cleaner than before and there are no more crashes.
This may have an impact on performance, and I have to be careful with that.
I mark this answer as correct for now, I may change it if someone else or I found something.
I am new to Vue and already ran into an issue that I can't solve.
I want to import a class from another .js file, where I will store my Axios requests. I have created a restDataFile.js file in my src folder:
import Axios from "axios";
const baseUrl = "my-api-address";
export default class {
async foo() {
await (Axios.get(baseUrl));
}
}
I wanted to import this class to another file (in my case it's my Vuex store file in my store/index.js file):
import RestDataSource from "./restDataSource";
Once I run build I get an error like this:
Failed to compile with 1 errors Error in ./src/restDataSource.js Module build failed (from ./node_modules/babel-loader/lib/index.js): TypeError: _core.types.isBigIntLiteral is not a function (...)
Import works fine if I do not export a class, so for example it works if I modify my restDataSource.js file to export:
export default {
foo() { ... }
}
Is it an issue with babel configuration or something? Can't find any solution to this error on the web.
I was trying to access the commercejs Library's Public Key in React. But i failed to do so and met with this error. I can't understand why i am getting this error.
src\lib\commerce.js
import Commerce from '#chec/commerce.js';
export const commerce = new Commerce(process.env.REACT_APP_CHEC_PUBLIC_KEY, true);
src\App.js
import React, {useState, useEffect} from 'react';
import {Products, Navbar} from './components';
import {commerce} from './lib/commerce';
const App = () => {
const [products, setProducts] = useState([]);
const fetchProducts = async () => {
const {data} = await commerce.products.list();
setProducts(data);
}
useEffect(() => {
fetchProducts();
})
console.log(products);
return (
<div>
<Navbar/>
<Products/>
</div>
)
}
export default App;
Error
TypeError: t is undefined
e
node_modules/#chec/commerce.js/lib/index.js:1
Ah, I see you're a man of culture as well, watching Javascript Mastery on Youtube!
Just check where you created the .env file. It should be stored in the root folder. I had it in my src folder that's how I got this error. If it doesn't work, then go to your commercejs client, login and then at your settings, refresh your PUBLIC API. When you get a new one, just replace it. It should work after this.
Robbie from Commerce.js here. We've had a number of issues from people following this tutorial, so here are a couple of things to watch out for:
Make sure your .env file is in your project's root folder (the same folder that your package.json file is in)
Ensure you have installed the dotenv package. You can make sure by running npm install dotenv or yarn add dotenv.
Put your public key in your .env file under the REACT_APP_CHEC_PUBLIC_KEY variable and ensure that your API key is valid. You can fetch your valid API keys from the Chec Dashboard.
Restart your local dev server after making changes to your .env file.
Hope this helps 👋
I got to same error. You should write terminal npm install #chec/commerce.js and npm install -g #chec/cli or visit the website commerce.js => "https://dashboard.chec.io/" .
I also face this issue when I watching Javascript Mastery on Youtube. What I did was, disconnect the connection with .env file and just add the public key to commerce.js.This is not the best practice.
export const commerce = new Commerce("Your public key", true);
I'm currently learning ES6 & Webpack, and I've have a particular set of files that the import statement just won't work on. Here's the problem:
Sagas.js
import { deleteMe } from './DeleteMe';
import * as constants from '../Constants';
debugger;
DeleteMe.js
export const deleteMe = "Yep, it's loading";
console.log(deleteMe);
In the above file, deleteMe is not accessible from debugger (with Chrome Inspector). constants is.
And Constants.js
export const SET_COMMENTS = 'SET_COMMENTS';
Before debugger halts (in Chrome inspector), the "Yep, it's loading" does fire in the console, so the file itself is coming through.
I've tried:
import * as deleteMeStuff from ./DeleteMe to see if deleteMeStuff would populate. It doesn't
Restarting webpack-dev-server. No dice, no errors on compile. Throwing a debugger in ./DeleteMe confirms changes are coming through.
const deleteMe = "Yep, it's working"; export default deleteMe & import deleteMe from './DeleteMe' --> still no joy
At the debugger, I've just noticed _DeleteMe returns {deleteMe: "Yep, it's loading", __esModule: true}
Any idea what's going on here & how to fix it? I'm thoroughly confused. There are a ton of other import files working successfully in other files across my app.
You can't use default and const in same line like
export default const deleteMe = "Yep, it's working"
You have to break it like:
export const deleteMe = "Yep, it's loading";
export default deleteMe;
and to import it you can do any one of following:
import deleteMe from './DeleteMe';
or
import { deleteMe } from './DeleteMe';
I'm new to React and I'm trying to import a JSON DATA variable from an external file. I'm getting the following error:
Cannot find module "./customData.json"
Could some one help me? It works if I have my DATA variable in index.js but not when it's in an external JSON file.
index.js
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import customData from './customData.json';
import Profile from './components/profile';
import Hobbies from './components/hobbies';
class App extends Component {
render() {
return (
<div>
<Profile name={this.props.profileData.name}imgUrl={this.props.profileData.imgURL} />
<Hobbies hobbyList={this.props.profileData.hobbyList}/>
</div>
);
}
}
ReactDOM.render(<App profileData={DATA}/>, document.querySelector('.container'));
hobbies.js
import React, {Component} from 'react';
var Hobbies = React.createClass({
render: function(){
var hobbies = this.props.hobbyList.map(function(hobby, index){
return (<li key={index}>{hobby}</li>);
});
return (
<div>
<h5>My hobbies:</h5>
<ul>
{hobbies}
</ul>
</div>
);
}
});
export default Hobbies;
profile.js
import React from 'react';
var Profile = React.createClass({
render: function(){
return (
<div>
<h3>{this.props.name}</h3>
<img src={this.props.imgUrl} />
</div>
)
}
});
export default Profile
customData.json
var DATA = {
name: 'John Smith',
imgURL: 'http://lorempixel.com/100/100/',
hobbyList: ['coding', 'writing', 'skiing']
}
export default DATA
One nice way (without adding a fake .js extension which is for code not for data and configs) is to use json-loader module. If you have used create-react-app to scaffold your project, the module is already included, you just need to import your json:
import Profile from './components/profile';
This answer explains more.
This old chestnut...
In short, you should be using require and letting node handle the parsing as part of the require call, not outsourcing it to a 3rd party module. You should also be taking care that your configs are bulletproof, which means you should check the returned data carefully.
But for brevity's sake, consider the following example:
For Example, let's say I have a config file 'admins.json' in the root of my app containing the following:
admins.json
[{
"userName": "tech1337",
"passSalted": "xxxxxxxxxxxx"
}]
Note the quoted keys, "userName", "passSalted"!
I can do the following and get the data out of the file with ease.
let admins = require('~/app/admins.json');
console.log(admins[0].userName);
Now the data is in and can be used as a regular (or array of) object.
With json-loader installed, you can use
import customData from '../customData.json';
or also, even more simply
import customData from '../customData';
To install json-loader
npm install --save-dev json-loader
Simplest approach is following
// Save this as someJson.js
const someJson = {
name: 'Name',
age: 20
}
export default someJson
then
import someJson from './someJson'
React 17 created from create-react-app, importing json just work by default.
import config from './config.json'
The solution that worked for me is that:-
I moved my data.json file from src to public directory.
Then used fetch API to fetch the file
fetch('./data.json').then(response => {
console.log(response);
return response.json();
}).then(data => {
// Work with JSON data here
console.log(data);
}).catch(err => {
// Do something for an error here
console.log("Error Reading data " + err);
});
The problem was that after compiling react app the fetch request looks for the file at URL "http://localhost:3000/data.json" which is actually the public directory of my react app. But unfortunately while compiling react app data.json file is not moved from src to public directory. So we have to explicitly move data.json file from src to public directory.
Please store your JSON file with the .js extension and make sure that your JSON should be in same directory.
// rename the .json file to .js and keep in src folder
Declare the json object as a variable
var customData = {
"key":"value"
};
Export it using module.exports
module.exports = customData;
From the component that needs it, make sure to back out two folders deep
import customData from '../customData';
In current react build you simply import and use:
import jsonData from 'path/to/myJson.json'
try with export default DATA or module.exports = DATA
there are multiple ways to do this without using any third-party code or libraries (the recommended way).
1st STATIC WAY: create a .json file then import it in your react component example
my file name is "example.json"
{"example" : "my text"}
the example key inside the example.json can be anything just keep in mind to use double quotes to prevent future issues.
How to import in react component
import myJson from "jsonlocation";
and you can use it anywhere like this
myJson.example
now there are a few things to consider. With this method, you are forced to declare your import at the top of the page and cannot dynamically import anything.
Now, what about if we want to dynamically import the JSON data? example a multi-language support website?
2 DYNAMIC WAY
1st declare your JSON file exactly like my example above
but this time we are importing the data differently.
let language = require('./en.json');
this can access the same way.
but wait where is the dynamic load?
here is how to load the JSON dynamically
let language = require(`./${variable}.json`);
now make sure all your JSON files are within the same directory
here you can use the JSON the same way as the first example
myJson.example
what changed? the way we import because it is the only thing we really need.
I hope this helps.
var langs={
ar_AR:require('./locale/ar_AR.json'),
cs_CZ:require('./locale/cs_CZ.json'),
de_DE:require('./locale/de_DE.json'),
el_GR:require('./locale/el_GR.json'),
en_GB:require('./locale/en_GB.json'),
es_ES:require('./locale/es_ES.json'),
fr_FR:require('./locale/fr_FR.json'),
hu_HU:require('./locale/hu_HU.json')
}
module.exports=langs;
Require it in your module:
let langs=require('./languages');
regards
This worked well in React 16.11.0
// in customData.js
export const customData = {
//json data here
name: 'John Smith',
imgURL: 'http://lorempixel.com/100/100/',
hobbyList: ['coding', 'writing', 'skiing']
}
// in index.js
import { customData } from './customData';
// example usage later in index.js
<p>{customData.name}</p>
My friends, if you are using React and TypeScript, just do these steps and DONE!
In the tsconfig.json add these 2 new lines:
// tsconfig.json
{
"compilerOptions": {
// ... other options
"esModuleInterop": true,
"resolveJsonModule": true
}
}
Import your json:
import yourJSON from "./data/yourJSON.json"
Something that worked for me was to simply place the JSON file in the public folder. You can simply import in any js using
brain.loadData("exampleFile.json");
It is as simple as that I guess. Definitely worth a try :D