To illustrate the problem i started a new App using the create-react-app tool (from https://github.com/facebook/create-react-app)
I want to be able to load in data from CSV files, I am using the CSV method from d3:
csv('data.csv').then(data => {
console.log(data)
});
I added this function to the App.js file:
import React from 'react';
import './data.csv';
import { csv } from 'd3'
function App() {
csv('data.csv').then(data => {
console.log(data)
});
return (
<div className="App">
</div>
);
};
export default App;
Every time I attempt this the code returns an Array of the Index.html code (pictured) instead of the data in the CSV file. I am sure as to why this is happening?
The CSV file is in the /src folder
Screenshot of console log
Let me first explain what went wrong. In your code, you are trying to access the file which is not there. And I'm not talking about the import. After the import when you are using the file name in csv function it doesn't have a proper path.
use this import statement - import data from './data.csv';
once application is compiled the data have the url of the file. Now if you console.log the data you'll get this - /static/media/data.csv
Note: Path may differ based on the tool used for compilation. I'm using yarn.
Now pass the data into csv function like this:
csv(data).then(response => {
console.log(response)
})
I hope this helps you understand how this is working. Refer the code shown below for the calling structure.
function App(){
console.log(data);
csv(data).then(response => {
console.log(response)
})
return (
<div className="App">Test</div>
);
}
If you have any questions or queries feel free to reach out.
Cheers :)
You need to perform the csv action somewhere in return part of the function like
import React from 'react';
import './data.csv';
import { csv } from 'd3'
function App() {
return (
<div className="App">
{csv('data.csv').then(data => {
console.log(data)
// perform all here
});}
</div>
);
};
export default App;
also you dont need to import the csv and correct csv path should be given in csv function. The most probable issue is you are not getting the file due to incorrect path.
Try importing your dataset first using React's method and then parse it using D3.csv function
import React from 'react';
import data from './data.csv';
import { csv } from 'd3';
function App() {
csv(data, function(error, data) {
if (error) throw error;
console.log(data);
});
return (
<div className="App">
</div>
);
};
export default App;
Related
I am trying out a small sample in nextjs. All that the proj does is to fetch json data from a file and try displaying it in list of a component. But the behavior is weird. Its getting into infinite loop and I have no clue what's wrong. Could some one take a look at https://github.com/SamplesForMurthy/sampleCode and help me figure out what the issue is? Not able to fetch the data nor I am able to display.
I cloned and fixed. You don't need to use fs.readFileSync here, or fs at all for that matter. You can simply import the .json file as an arbitrarily named variable then map it out.
Here is how I got the data rendering:
import React from 'react';
import testData from '../TestData/SampleData.json';
import SampleParentComponent from '../components/SampleParentComponent';
function TestPage({ filecontent }) {
console.log(`filecontent: ${filecontent}`);
return (
<div>
<SampleParentComponent data={filecontent}></SampleParentComponent>
</div>
);
}
export const getStaticProps = async ctx => {
console.log(ctx.query);
const filecontent = await testData;
return {
props: { filecontent }
};
};
export default TestPage;
/**
* (property) filecontent: {
data: {
seqNo: number;
contactName: string;
}[];
}
*/
I'm trying to have my add data from a local static JSON file to the Vue vuex store.
I want my JSON file separated from the bundle process, so that i can change the content anytime in future, without rebuilding the whole site.
I have my json file [test.json] in the public folder
And with the following code, i managed to import the data, but its still being bundled on build of the site.
import data from '../public/test';
export const state = () => ({
allData: {}
})
export const mutations = {
SET_ALL_DATA(state, data) {
state.allData = data
}
}
export const actions = {
nuxtServerInit({ commit }) {
commit('SET_ALL_DATA', data)
}
}
I have also tried hosting the JSON file on a web server and doing an axios call to it on nuxtServerInit like so. but the called upon json file still gets bundled, as changing the hosted json file does nothing to update the content.
export const actions = {
async nuxtServerInit ({ commit }, { $axios }) {
const res = await $axios.$get('https://www.amq.fariskassim.com/testjson/test.json')
commit('SET_ALL_DATA', res)
}
}
I'm all out of solutions so if anyone can point me in the right direction, i would be totally grateful
I am trying to import a CSV for use with the D3 library to create a chart within a Create React App project, but importing the file is throwing a "Cannot find module" error even though the path to the CSV file is correct.
I have a feeling this might be something to do with CRA's Webpack config under the hood but it looks like this is using the file loader so I'm not sure what the issue is. The data file is within CRA's src directory.
The console log in the code below is running with the correct data in, which means the data must be being accessed. The error is thrown after this (Although the path to the CSV is underlined red in my editor).
I am using TypeScript but I don't think this has anything to do with the problem.
import React from 'react';
import * as d3 from 'd3';
import CSVData from '../data/data.csv';
const BarChart: React.FC = () => {
d3.csv(CSVData).then(res => {
console.log(res);
});
return <div>Test</div>;
};
export default BarChart;
CRA doesn't support importing .csv files. Without ejecting from CRA, your best option is to copy that file along with the results of yarn/npm build to your web server and then fetching it at runtime.
If that CSV is big (more than a few kb), then it is also the better option in terms of performance/code splitting.
Thanks to Nick Ribal for his answer, I found a similar solution by moving my data file into the public folder and then referencing this via the PUBLIC_URL environment variable.
I used the D3 CSV method which will get data from a URL if passed one rather than using fetch and parsing this as text.
With D3 CSV method:
import React, { useState } from 'react';
import { DSVRowArray } from 'd3';
import * as d3 from 'd3';
type CSVData = DSVRowArray | null;
const BarChart: React.FC = () => {
const initialState: CSVData = null;
const [fetchedCSVData, setFetchedCSVdata] = useState<CSVData>(initialState);
if (!fetchedCSVData) {
d3.csv(`${process.env.PUBLIC_URL}/data/data.csv`).then(res => {
setFetchedCSVdata(res);
});
}
return <div>Test</div>;
};
export default BarChart;
Without D3 CSV method:
import React, { useState } from 'react';
type CSVData = string | null;
const BarChart: React.FC = () => {
const initialState: CSVData = null;
const [fetchedCSVData, setFetchedCSVData] = useState<CSVData>(initialState);
if (!fetchedCSVData) {
fetch(`${process.env.PUBLIC_URL}/data/data.csv`)
.then(res => res.text())
.then(stringData => {
console.log(stringData);
setFetchedCSVData(stringData);
});
}
return <div>Test</div>;
};
export default BarChart;
So I'm practicing React and Redux, and I'm loading a local json file into the store like this ...
import { LOAD_BOOKS } from "./booksConstants";
import axios from "axios";
export const loadBooks = data => {
return {
type: LOAD_BOOKS,
payload: data
};
};
export const asyncLoadBooks = () => {
return async dispatch => {
const response = await axios.get("books.json");
const data = response.data.books;
dispatch(loadBooks(data));
};
};
And here's the reducer ...
import { LOAD_BOOKS } from "./booksConstants";
import { createReducer } from "../../store/reducerUtil";
const initialState = {
books: []
};
export const loadBooks = (state, payload) => {
return {
...state,
books: payload
};
};
export default createReducer(initialState, {
[LOAD_BOOKS]: loadBooks
});
And I'm connecting the App.js to the store with connect() and firing the 'asyncLoadBooks()' in 'componentDidMount()' like this ...
componentDidMount() {
try {
this.props.asyncLoadBooks();
} catch (error) {
console.log(error);
}
}
And everything is working just fine when I loop over the data and display them, however, if I'm on any other route other than "/" and refresh the app manually it gives me this error Failed to load resource: the server responded with a status of 404 (Not Found)
I tried to move the methods to the constructor instead of 'componentDidMount' but it didn't work.
What should I do here? And please keep in mind that I want to use axios and redux to practice them.
Edit
I put a console.log into each async action creator and apparently when I'm on any route other than the home "/" it tries to get the JSON file from this path and can't find it GET http://localhost:3000/category/books.json 404 (Not Found)
How can I solve this?
Ok, guys, I figured it out, the problem was in axios trying to the fetch the JSON file from different paths when you're on different routes, I fixed that by setting a global default baseURL for axios in the index.js file like this ...
import axios from "axios";
axios.defaults.baseURL = "http://localhost:3000/";
And now you can refresh in any route and the data will be fetched successfully.
Can't find this exact question answered. I want to have a data.JSON file in my /public folder which contains a static file which once site is built I can quickly modify without having to rebuild the site. However I'm struggling on how to get this into react. I've tried following instructions from the README, but it's a bit unclear.
If I try:
class Home extends Component {
render() {
const data = require(`${process.env.PUBLIC_URL}/data.json`);
I get the message on compile:
./src/Home.js
Module not found: You attempted to import /data.json which falls outside of the project src/ directory. Relative imports outside of src/ are not supported. You can either move it inside src/, or add a symlink to it from project's node_modules/.
What's the proper way to include it? I also tried a hacky way by trying to write it to window.DATA in public/index.html but because I believe it has to call Asynchronous (otherwise chrome gives me an error) sometimes the data will be there, sometimes not, and React doesn't seem to like it. Code I tried:
var request = new XMLHttpRequest();
request.open("GET", "%PUBLIC_URL%/data.json", true);
request.send(null);
request.onreadystatechange = function() {
if ( request.readyState === 4 && request.status === 200 ) {
window.DATA = JSON.parse(request.responseText);
}
}
Any help would be appreciated!
Borrow the "window" variable.
For example, in file "/public/config.js":
window.samleAppConfig = {
entryUrl: "service.com/api"
}
Then in file "/src/App.js":
constructor(props) {
super(props);
console.log('entryUrl', window.samleAppConfig. entryUrl);
}
And in "/public/index.html":
<div id="root"></div>
<script type="text/javascript" src="config.js"></script>
Your first solution will not work if you want to put file in public folder as React should not give access to something outside the source folder. Otherwise you can imagine a bad code could allow people access folder c:\windows
Your second solution could be the way to go, but just need a little bit work on the callback. If you start your project with create-react-app, you can put index.js as
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
var xhttp = new XMLHttpRequest();
var data = {};
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
// Typical action to be performed when the document is ready:
data = JSON.parse(xhttp.responseText);
ReactDOM.render(<App appData={JSON.stringify(data)}/>, document.getElementById('root'));
}
};
xhttp.open("GET", `${process.env.PUBLIC_URL}/data.json`, true);
xhttp.send();
And then your App.js as
import React, { Component } from 'react';
class App extends Component {
render() {
return (
<div>
<h2>{JSON.parse(this.props.appData).Name}</h2>
</div>
);
}
}
export default App;
I put data.json in the public folder, and I have the object like this:
{
"Name": "My App"
}
I tried it just now and it can show My App in the page all the time
You can simply do it like this:
mydata.js
export default {
myStuff: [ "one","two","three"]
}
In your code
import myData from './mydata.js'
You now have your data in a variable called myData