Is there a way to read a local JSON array in ES6? - javascript

Hi to whoever may read this! Would like to thank in advance any help or direction towards further research into this topic as I'm not sure I fully understand the logic.
I'm creating a react app which uses a button component and gets it's props from an external but local JSON array made up of names. For instance:
import React from 'react';
import * as buttonNames from '/localdirectory/buttonNames.json';
class Buttons extends React.Component {
render() {
return (
{buttonNames.map((buttonName, i) => {
return <button>{buttonName}</button>
}}
);
}
}
And the JSON array looks like this:
[
"10A",
"10B",
"10C",
"10D",
"10E",
"10F"
]
This is a simplified example of what I'm trying to do however the expected result from my perspective is that the mapping function should iterate through the JSON array and assign each to the buttonName variable which would then be used to create 6 different buttons with the innerHTML filled by the content of the array item.
However the program throws an error which states that map is not exported from the JSON array, why would it need to be in the first place? Shouldn't the program be simply importing it and treating it as a standard array which has built-in JS methods such as map and forEach
I've tried working with the file as a CSV and importing using D3, however that returns a promise which I'd prefer not to be the case as I'm using it load the UI and the file which contains the buttonNames isn't particularly large. Using JSON.parse() also does not work as the program states that the target is already an object.
Appreciate and open to any suggestions!

It's about your import statement.
while handling JSON file in js, it's been turned into a js that export data.
[1,2,3]
with
import data from "./data.json"
console.log(data) // [1,2,3]
with
import * as data from "./data.json"
console.log(data) // {0:1,1:2,2:3, default:[1,2,3]}
as it's been treated as ES module, so you import an object instead of the array itself, so the map function will be undefined, as it's just a plain object.
Here's why
Webpack load JSON with json-loader, which is officially supported that you won't need to configure yourself, and the json-loader will handle JSON files by stringify it and concat with module.exports=, source code here,
so the JSON will be in js like
module.exports = [0,1,2]
and as the module.exports object itself will be imported as default export in an ESM file, and all objects fields will be export as others, so you will get an ESM object while doing import * as data from "./data.json"
Of cause if you are using a different JSON loader the value will be different, but the error is what you meet.

Yes you're right, JSON array should be treated as native in JS. It is. You don't have to change your JSON. Problem is the import * syntax, do not use it. Instead:
import buttonNames from '/localdirectory/buttonNames.json';
Which will be imported smoothly by Webpack.

Plain JSON does not Support Arrays. Try:
{
0: "10A",
1: "10B",
2: "10C",
3: "10D",
4: "10E",
5: "10F"
}
import React from 'react';
import buttonNames from '/localdirectory/buttonNames.json';
class Buttons extends React.Component {
render() {
return (
{Object.values(buttonNames).map((buttonName, i) => {
return <button>{buttonName}</button>
}}
);
}
}

Working demo
Json file
{
"data": ["10A", "10B", "10C", "10D", "10E", "10F"]
}
JSX
import React from "react";
import "./styles.css";
import { data } from "./myJson.json";
export default function App() {
console.log(data);
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
{data.map(d => (
<p>{d}</p>
))}
</div>
);
}

Related

Instance of a functional component is said to be unrecognized in browser. Why is that?

I am using a JSON format text file to import items from there to another js file using react. I am using the map method in JS to iterate through the item in the JSON file. However an error keeps popping up that my functional component is unrecognized.
import React from "react"
import products from "./vschoolProducts"
import product from "./product"
function App() {
const listofp = products.map(function(pro){
return <product key={pro.id} product= {pro} />
})
return (
<div>
{listofp}
</div>
)
}
export default App
Any ideas of why it is unrecognized ?
It's silly of me, but the error can be resolved simply by making the first letter of the react component in upper caps.
The product component in product.js needs to be changed to Product.
Subsequently every instance of product must be changed to Product.
Functional components must always start with Caps.

export was not found -- but names still work

I'm sure this is obvious, but I'm not seeing why this isn't working at the moment...
I have a file in a Vue project that exports keycodes in a couple different formats, one to be used for constants (allCodes) and another to be used for Vue (keyCodes):
export default {
allCodes,
keyCodes
};
When I try to import one of them using deconstruction like this, I get an error:
import { allCodes } from '#/helpers/keycodes';
21:17-25 "export 'allCodes' was not found in '#/helpers/keycodes'
warning in ./src/mixins/GlobalKeyPressHandler.js
However, importing then referring to the key by name works:
import object from '#/helpers/keycodes';
console.log('allCodes', object.allCodes);
What gives?
If you want named exports it should be
export {
allCodes,
keyCodes
};
Currently you are exporting an object as default.
BTW "I try to import one of them using deconstruction like this" if you mean that you are trying to use destructuring assignment in imports it wont work. Named import statement is not object destructuring though it looks alike in simplest case.
If you want to have default export than you should make assignment below the import statement
export default {
allCodes,
keyCodes
};
// importing side
import keycodes from '#/helpers/keycodes';
const { allCodes } = keycodes;

Typescript equivalent of PropTypes.oneOf, from existing variable

I know that this has been asked-and-answered in What is the TypeScript equivalent of "PropTypes.oneOf" (restrict a variable to subset of values), but I have a case where I don't feel like the answer solves my issue yet.
I am working on converting a project from JavaScript to Typescript. In one React component, a JSON file is imported. One of the props in the component must be one of the keys of this JSON:
import React from "react"
import PropTypes from "prop-types"
import myData from "./myData.json"
const dataKeys = Object.keys(myData)
function MyComponent({myType, ...}) { ... }
MyComponent.propTypes = {
myType: PropTypes.oneOf(dataKeys).isRequired,
...
}
I now want to convert MyComponent into Typescript, so I'm going to remove PropTypes and create a Props interface based off of the existing propTypes. The thing is, I am unsure how to convert PropTypes.oneOf which is built off of an existing variable, especially one that depends on an import of a JSON file. Normally, I would use a union of string literals or an enum type. What are my options in this case?
Yes, I have allowSyntheticDefaultImports enabled in tsconfig.json.
Assuming iconNames is an array, this StackOverflow answer should help: Typescript derive union type from tuple/array values
Basically, when you define iconNames, define the type along with it:
const iconNames = ['plus', 'arrow', 'trash'] as const;
type IconNamesType = typeof iconNames[number];

React Native - exporting an object based on switch case loop

I'm new to React Native and I'm struggling with an object exporting problem. In my app, I'm receiving from back-end simple string that I store in a variable Settings.translationType. When it's received, I'm rendering a simple view, let's say like this:
import React, { Component } from 'react';
import { Text, View } from 'react-native';
import Translations from '../constants/Translations';
export default class HomeScreen extends Component {
render() {
return(
<View>
<Text>{Translations.one}</Text>
</View>
)
}
}
And there comes to some troubles. I'm having a .js file (Translations), that depends on what comes from back-end service, it gives proper translated category names. It looks like this:
import Category1 from './translations/Category1';
import Category2 from './translations/Category2';
import Category3 from './translations/Category3';
const Translations = () => {
switch (Settings.translationType) {
case '2':
return Category2;
case '3':
return Category3;
default:
return Category1;
}
}
export default Translations();
Inside the ./translations folder, I'm having three .js files like below:
import LocalizedStrings from 'localized-strings';
const Category1 = new LocalizedStrings({
en: {
one: 'Restaurant',
two: 'Café',
three: 'Pub'
},
fi: {
one: 'Ravintola',
two: 'Kahvila',
three: 'Pub'
},
sw: {
one: 'Restaurang',
two: 'Kafé',
three: 'Pub'
},
de: {
one: 'Restaurant',
two: 'Cafe',
three: 'Pub'
},
})
export default Category1;
After I run my app in Expo CLI, the Settings.translationType is always fetched correctly from BE, but I'm having an error like: Unable to resolve module './translations/Category1.js' from '~/RN/MyProject/src/constants/Translations.js': The module './translations/Category1.js' could not be found from '~RN/MyProject/src/constants/Translations.js'. Indeed, non of these files exists: (and there are listed the files with other extensions of Category1 file, located at ~/RN/MyProject/src/constants/translations/)
I think I'm having some logical problem (syntax looks ok) so if I'm missing something or there is any other solution, thank you in advice!
EDIT:
Added my folder structure.
Okay I think I found your problem. In Translations.js your export statement should be
export default Translations;
instead of
export default Translations();
Also make sure all your Category files are exported the same way.
See if this works.
I found that in my source file I have misspelled the file's path, syntax bugs are the worst. After that change, all works correct. And just for your knowledge Atin Singh, export default Translations without braces passes '' instead of the proper translation string. Thanks all for your help!

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