How to have a external JSON config file in react jsx - javascript

I want to have a external configuration file (JSON) in my React based project. That is the ultimate outcome or when I deliver it (public folder and the bundle.js) my configuration file also should be given. The User should be able to change the configurations according to his or her wish and use my app. That is there without recompiling my code one should be able to use it. In other words configuration file should not bundle with my app.

The accepted answer may work. However, why make it so complicated?
Step#1.
Create a file Config.js, with content
var Configs = {
prop1 = "abc",
prop2 = "123"
}
Step#2. Load the file in index.html via script tag.
<div id='root'></div>
<script src="Config.js"></script>
<script src="dist/bundle.js"></script></body>
Step#3. Just access the setting directly within any React component.
class MyComponent extents Component {
render() {
//you can access it here if you want
let myprop1 = window.Configs.prop1;
return(){
<div>myprop2 is: {window.Configs.prop2}</div>
}
}
}
Step#4. Profit?
Does not require or need to involve webpack, webpack-externals, webpack-config, import Config from 'config', or any other BS.
Why it works? because we declared 'Configs' to be a prop of the window object, and loaded it globally.

Like Joseph Fehrman said without thinking only about the JSON, using JS worked for me. This is what I did.
I created a JS file called configurations.js which included my required configurations
var configs = {
"aUrl": "https://localhost:9090/",
"bUrl": "https://localhost:9445/"};
Then in the index.html I added it.
<body>
<div id='root'></div>
<script src="configurations.js"></script>
<script src="dist/bundle.js"></script></body>
Then in the webpack.config.js I added it to externals like this. (Note that in the configurations.js, name of the variable is configs).
externals: {
config: "configs",
}
Then in where ever I want it, I can import it and use it nicely. This worked perfectly where I was able to change the configurations after it was deployed (That is did not have to recompile the code where my bundle.js remained untouched :-)).
An example showing how it was used is given below.
import { Component } from 'react';
import axios from 'axios';
import Config from 'config';
/**
* #class GetProductAreas
* #extends {Component}
* #description Get ProductAreas
*/
class GetProductAreas extends Component {
/**
* #class GetProductAreas
* #extends {Component}
* #description get product areas
*/
getproductAreas() {
const url = Config.aUrl;
return axios.get(url).then((response) => {
return (response.data);
}).catch((error) => {
throw new Error(error);
});
}
}
export default (new GetProductAreas());

The question is a bit vague. I think I know what you are asking for. As long as you are planning on using Webpack or Browserify you could do the following. It does require slightly different thinking instead of a pure JSON file using a JS file to mask it.
config.js:
let config = {
option1: true,
option2: false
}
module.exports = config;
And then from your file using the configuration you could do something similar to the following.
app.js:
import React from 'react';
import ReactDOM from 'react-dom';
import config from './my/relative/config/path/config';
import MyOtherComponent from './components/my_component';
let component = (<MyOtherComponent config={config} />);
ReactDOM.render(component, document.querySelector('mount'));

Last solution worked great, here's some improvements:
Config file, in /public folder:
config.js
var Configs = {
var1: "value",
var2: "value2"
}
In /public/index.html file, add script call in the header
<head>
....
<script src="config.js"></script>
....
</head>
Last, call the var from the code. Works great!
import React from 'react'
....
const data = window.Configs.var1
With this solution I can have several servers without recompiling, and it's easy to do.

Related

How to import lodash library in js file [duplicate]

I'd like to import this javascript package in React
<script src="https://cdn.dwolla.com/1/dwolla.js"></script>
However, there is no NPM package, so I can't import it as such:
import dwolla from 'dwolla'
or
import dwolla from 'https://cdn.dwolla.com/1/dwolla.js'
so whenver I try
dwolla.configure(...)
I get an error saying that dwolla is undefined. How do I solve this?
Thanks
Go to the index.html file and import the script
<script src="https://cdn.dwolla.com/1/dwolla.js"></script>
Then, in the file where dwolla is being imported, set it to a variable
const dwolla = window.dwolla;
This question is getting older, but I found a nice way to approach this using the react-helmet library which I feel is more idiomatic to the way React works. I used it today to solve a problem similar to your Dwolla question:
import React from "react";
import Helmet from "react-helmet";
export class ExampleComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
myExternalLib: null
};
this.handleScriptInject = this.handleScriptInject.bind(this);
}
handleScriptInject({ scriptTags }) {
if (scriptTags) {
const scriptTag = scriptTags[0];
scriptTag.onload = () => {
// I don't really like referencing window.
console.log(`myExternalLib loaded!`, window.myExternalLib);
this.setState({
myExternalLib: window.myExternalLib
});
};
}
}
render() {
return (<div>
{/* Load the myExternalLib.js library. */}
<Helmet
script={[{ src: "https://someexternaldomain.com/myExternalLib.js" }]}
// Helmet doesn't support `onload` in script objects so we have to hack in our own
onChangeClientState={(newState, addedTags) => this.handleScriptInject(addedTags)}
/>
<div>
{this.state.myExternalLib !== null
? "We can display any UI/whatever depending on myExternalLib without worrying about null references and race conditions."
: "myExternalLib is loading..."}
</div>
</div>);
}
}
The use of this.state means that React will automatically be watching the value of myExternalLib and update the DOM appropriately.
Credit: https://github.com/nfl/react-helmet/issues/146#issuecomment-271552211
for typescript developers
const newWindowObject = window as any; // cast it with any type
let pushNotification = newWindowObject.OneSignal; // now OneSignal object will be accessible in typescript without error
You can't require or import modules from a URL.
ES6: import module from URL
What you can do is make an HTTP request to get the script content & execute it, as in the answer for how to require from URL in Node.js
But this would be a bad solution since your code compilation would depend on an external HTTP call.
A good solution would be to download the file into your codebase and import it from there.
You could commit the file to git if the file doesn't change much & are allowed to do it. Otherwise, a build step could download the file.
var _loaded = {};
function addScript(url) {
if (!loaded[url]) {
var s = document.createElement('script');
s.src = url;
document.head.appendChild(s);
_loaded[url] = true;
}
}
how to load javascript file from cdn server in a component
Add the script tag in your index.html and if you are using Webpack, you can use this webpack plugin https://webpack.js.org/plugins/provide-plugin/

Cannot import Javascript file in other Javascript file

For a project, I'm using Django for my backend, HTML/CSS/JS for frontend.
For one HTML page, I use two JS files: dom_creator.js and console_page.js. I would like to use the functions of dom_creator in console_page, but whatever I try, I cannot find the right statement to import (and many of the ES6 import statements even make my console_page.js to stop working).
I also have a module imported to my HTML (console_module.js). In that file, I have no issue importing dom_creator.js with
import {function1, function2} from "./dom_creator.js"
How would I be able to import functions from dom_creator in console_page.js (which is not a module)? I've tried all suggestions on Stack Overflow, but none of them seem to work.
the problem maybe in html code when you tried to import js files
add TYPE = "MODULE" to script element
script type="module" src="./myscript.js" script
and at js file to import, use
function print(y){
console.log(y);
}
export {print};
to import the x function in another js file do the following:
import {print} from "./main.js" // dont forget .js
// another way to import all functions
import * as main from "./main.js" // dont forget .js
//to use the last one:
let variable = main.print('hello word');
For importing a function into the other file, first, you need to export it,
so if you are using es5 (mostly the case in NodeJs) you need to export it as below:
var myfunction = function () {}
module.exports = { myfunction }
and in newer versions (es6+) you can use export like this:
var myfunction = function () {}
export myfunction;
// then you can import it like: import {myfuntion} from 'file.js';
// or with another name: import {myfuntion as john} from 'file.js';
// or export it as default like:
export default myfunction;
// then you can import it like import myfuntion from 'file.js';
// or any other custom name: import john from 'file.js';
the only thing I couldn't understand from your question is the relation of with question with Django 🤔

Import types from .graphql into a .js file

I've searched something about import types from .graphql files. I’ve found graphql-import to import using # import something from 'something-else'. This works fine between .graphql files.
But what I’m trying to do is to import some types from generated.graphql from Prisma into a .js file.
For example:
I have this generated.graphql file from Prisma
"""generated.graphql file"""
type ItemWhereInput { ... }
type ItemConnection { ... }
...
I would like to import those two types ItemWhereInput and ItemConnection from generated.graphql file into items-types.js file
// items-types.js file
import gql from 'graphql-tag';
// I would like to make some kind of import ItemWhereInput and ItemConnection here
// Something like `import { ItemWhereInput, ItemConnection } from 'generated.graphql'`
...
const ItemWhereUniqueInput = gql`
input ItemWhereUniqueInput {
id: String!
}
`;
...
// And export ItemWhereInput and ItemConnection here
export default [Item, ItemInput, ItemWhereUniqueInput, ItemUpdateInput];
That way I could call makeExecutableSchema from graphql-tools and use those types in some place else
// items-query.js file
import { forwardTo } from 'prisma-binding';
const schema = `
items: [Item]!
item (where: ItemWhereUniqueInput!): Item
# And use it here
itemsConnection (where: ItemWhereInput): ItemConnection!
`;
const resolvers = {
items: forwardTo(‘db’),
item: forwardTo(‘db’),
itemsConnection: forwardTo(‘db’),
};
export default {
schema,
resolvers,
};
If it is somewhere else or there are something that could help, please, point me out.
Thanks.
You should be able to do the following:
During your build step, first, transform your generated.graphql file into a js file by
adding export default ` to the beginning of the file,
`); to the end of the file, and
renaming it to generated.js.
This way, you can import the file just as a js file in your development code:
// some other js file
/*
* notice the lack of .js, this should make it easier for your
* IDE to understand you're referencing the 'generated.graphql' file.
* If this is not possible in your code, you actually have to say
* .js here, not .graphql, because the file will be called .js after
* build.
*/
import generated from './generated';
console.log(generated);
You will see that schema is a string of the contents of the file pre-build-step.
It can now be used as typeDefs for makeExecutableSchema:
import { makeExecutableSchema } from 'graphql-tools';
import typeDefs from './generated';
import resolvers from './resolvers';
const schema = makeExecutableSchema({
typeDefs,
resolvers,
});
If you use a bundler and/or transpiler some additional work has to be done, to make sure the file is also run through these tools.
The project I've used this approach on only uses babel, with which it is a matter of:
using npm-watch instead of babel's --watch option to run the build script
(can be done in parallel)
running babel on all source .js files
running a custom script on all .graphql files, which:
adds the relevant code to the file, to make it valid js (in-memory)
programmatically runs babel on the result
saves it to the build destination with .js extension
Careful with large files though, as they are loaded to memory with this method!
Beware though, as this approach does not work with a bundler, for which you will have to either transform the file before running the bundler (and somehow still retain the old version, probably by naming the transformed version differently and deleting it after running the bundler), or find/create a Plugin doing this work for you.
Here are some options I found (quick google search): for webpack and Parcel.

Dynamically import all component sub directories without using full path

I am using Next.js for React. I like how Arc (other react boilerplate) dynamically imports components without requiring developer to specify path.
import { Input, Label, Field, HomePage, PageTemplate } from 'components'
Folder structure may look somewhat like this:
components
|_ index.js
|_ atoms
|_ Input
|__ index.js
|_ molecules
|_ organisms
|_ templates
and I'd like to import it like:
import { Input } from 'components'
Code that is used for dynamic import: components/index.js
const req = require.context('.', true, /\.\/[^/]+\/[^/]+\/index\.js$/)
req.keys().forEach((key) => {
const componentName = key.replace(/^.+\/([^/]+)\/index\.js/, '$1')
module.exports[componentName] = req(key).default
})
However it doesn't work. The error I get:
Module not found: Error: Cannot resolve module 'components'...
The issue is that require.context is not available on serverside.
I suppose I need to specify this path to be imported like this in loader config. Can anybody share a hint on how is this done properly?
I don't think there is a simple and reliable way to do what you want with Next.js
The standard/"correct" answer is to use a relative path to import your local components. It is a bit more boilerplate, but I think you'll ultimately find it to be less work than fighting with Next.js to make it do things the Arc way.
To followup on #Robsonsjre's suggestion:
Why dont you make your /components/index.js export all components in the folder?
I think there is an implied "you write that index.js file". For your example, it would look something like this:
export {default as Input } from './atoms/Input';
export {default as Foo } from './molecules/Foo';
// etc
The catch is that you'd have to remember to update this file every time you add or remove a component. It's probably possible to automate that, but I'm not aware of any system to do it off the top of my head.
This way is not exactly what you want, but works similar, well for performance because its only object pointers to imported components
//Input.js
class Input extends Component {
render() {
return <div>'input'</div>
}
}
export default Input
//index.js
export { default as Input } from './Input/Input'
//otherComponent.js
import { Input } from './components' //path to folder components

Import JSON file in React

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

Categories