i have JSON like this
i want to use this JSON and display data in Table using react js.
this is how i display data from JSON file.
import React, { Component } from 'react';
import data from './data.json';
class App extends Component {
render() {
return (
<ul>
{
data.map(function(movie){
return <li>{movie.id} - {movie.title}</li>;
})
}
</ul>
);
}
}
export default App;
how to load JSON from URL and display it in table using reactjs?
You could fetch the JSON once the component will mount, and when you eventually resolve it you can update the state of the component:
import React, { Component } from 'react';
class App extends Component {
// initially data is empty in state
state = { data: [] };
componentDidMount() {
// when component mounted, start a GET request
// to specified URL
fetch(URL_TO_FETCH)
// when we get a response map the body to json
.then(response => response.json())
// and update the state data to said json
.then(data => this.setState({ data }));
}
render() {
return (
<ul>
{
this.state.data.map(function(movie){
return <li key={movie.id}>{movie.id} - {movie.title}</li>;
})
}
</ul>
);
}
}
export default App;
If you're unable to use fetch, you could use some other libraries like superagent or axios. Or you could even fall back to good ol' XMLHttpRequest.
On another note, when building a list of component it is important they each child have a unique key attribute. I also updated that in the code, with the assumption that movie.id is
Example axios code:
axios.get(URL)
.then(response => response.data)
.then(data => this.setState({ data }));
EDIT: as trixn wrote in a reply, componentDidMount is the preferred place to fetch data. Updated code.
EDIT 2: Added axios code.
You can use axios to send http requests.
It looks like this :
const response = await axios.get(your_url_here);
const items = response.data.items;
About await keyword : How to use await key word on react native?
This is axios GitHub page for the docs : https://github.com/axios/axios
Hope it helps.
You can use the fixed Data table to display the data from the json Response.Since the data is vast and it would be difficult to manage the conventional table, this would be a better alternative.
The documentation is given at
https://github.com/schrodinger/fixed-data-table-2/blob/master/examples/ObjectDataExample.js
This link will help you.
Related
I try to pass an array of object from localhost:5000/users to Table component as a prop but I can't.
I can fetch data from localhost:5000/users and when I try to do console.log inside it, I can see data. But when I try to do console.log outside fetch function, it returns an empty array.
The question is how can I pass the data to Table component if the data is not visible outside the fetch function ?
import React from 'react';
import './App.css';
import Table from './Table';
function App() {
let obj = [];
fetch('http://localhost:5000/users')
.then((response) => {
return response.json();
})
.then((data) => {
return obj = data;
})
.then(() => {
console.log(obj); // Here it returns correct data from localhost:5000/users
return obj;
});
console.log(obj); // But right here, it returns an empty array
return (
<div>
<Table data={obj} /> {/* The question is how can I pass data from localhost:5000/users to Table component ? */}
</div>
)
}
export default App;
You need to use state and useEffect state in React.js .
I would recommend to invest more time on useState and useEffect. To do so React.js official documentation is good source to study. Here is also some resource links: how to use useState
how to use useEffect
import React, {useState} from 'react';
import './App.css';
import Table from './Table';
function App() {
const [obj, setObj] = useState([])
useEffect(() => {
fetch("http://localhost:5000/users")
.then((response) => {
return response.json();
})
.then((data) => {
//return obj = data;
setObj(data); // setting obj using setObj
})
.then(() => {
console.log(obj); // Here it returns correct data from localhost:5000/users
return obj;
});
}, []);
console.log(obj); // But right here, it returns an empty array
return (
{/* The question is how can I pass data from localhost:5000/users to Table component ? */}
)
}
export default App;
A solution can be : Create a state inside a constructor in your class.
Now when you fetch, setState the data inside your state :)
Now if you create a function outside your fetch it can be like this
onClick = () => {
console.log(this.state.data)
}
Now, you can do what you want with your data on all your component :)
And if you want to use the same component for many data, your state need to be an array, and you need to map your state :)
Have fun
I think this is happening because the fetch API call is a promise, therefore, the second console.log console.log(obj); // But right here, it returns an empty array runs before the promise resolves.
You can use state and useEffect as mentioned by Rahul Amin. I have created a js fiddle you can checkout. here. https://jsfiddle.net/titbetegya/owk7eg2a/18/
I'm trying to solve this problem that I can't seem to solve with stripe's API's
So when creating a charge with their new version API they say that in the front end we should call
loadStripe('publishable Key',{'Connected account ID'})
and set that to a const.
now I dont undestand how are we supposed to get the ID that is stored somewhere say a database?
As a reference please look at this and here (In Step 3 ...).
What I'm currently doing is something like this
import React from "react";
import ReactDOM from "react-dom";
import { Elements } from "#stripe/react-stripe-js";
import { loadStripe } from "#stripe/stripe-js";
import CheckoutForm from "./CheckoutForm";
//btw I have set this to const and to let and none work
const stripePromise = fetch("url", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
anything: window.sessionStorage.getItem("Variable Account")
//here store something that will tell what account to pull ID data from
})
})
.then(data => data.json())
.then(result => {
return loadStripe("KEY", { stripeAccount: result });
});
class App extends React.Component {
render() {
return (
<Elements stripe={stripePromise}>
<CheckoutForm />
</Elements>
);
}
}
export default App;
but the const seems to not load correctly if one goes with the regular flow of the app say from
myapp.com/home
-> click
myapp.com/home/something
-> then
myapp.com/home/something/payment
stripe is not loading but one refreshes the browser now works but that tells me I'm doing maybe something wrong or I have to make the app refresh in 'componentDidMount()' maybe?
One can set it to be static but connected accounts can be many so if anyone can help me with this I would appreciate it
Generally, you'd want to have this account ID available in your app. But if you need to retrieve it, that's fine, but make sure the stripePromise is what you think it is. For example, I can make this work here with a simulated fetch call here: https://codesandbox.io/s/stripe-connect-w-resolve-wts34
Note that I'm managing the Promise explicitly:
const stripePromise = new Promise((resolve, reject) => {
fetch(...)
.then(data => data.json())
.then(result => {
resolve(
loadStripe(STRIPE_PUBKEY, { stripeAccount: "acct_xxx" })
);
});
});
The fact that you describe this breaking with navigation suggests you might be routing incorrectly. If this is a single page app, the navigation shouldn't cause the App component to re-render.
I have a simple component that fetches data and only then displays it:
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
loaded: false
stuff: null
};
}
componentDidMount() {
// load stuff
fetch( { path: '/load/stuff' } ).then( stuff => {
this.setState({
loaded: true,
stuff: stuff
});
} );
}
render() {
if ( !this.state.loaded ) {
// not loaded yet
return false;
}
// display component based on loaded stuff
return (
<SomeControl>
{ this.state.stuff.map( ( item, index ) =>
<h1>items with stuff</h1>
) }
</SomeControl>
);
}
}
Each instance of MyComponent loads the same data from the same URL and I need to somehow store it to avoid duplicate requests to the server.
For example, if I have 10 MyComponent on page - there should be just one request (1 fetch).
My question is what's the correct way to store such data? Should I use static variable? Or I need to use two different components?
Thanks for advice!
For people trying to figure it out using functional component.
If you only want to fetch the data on mount then you can add an empty array as attribute to useEffect
So it would be :
useEffect( () => { yourFetch and set }, []) //Empty array for deps.
You should rather consider using state management library like redux, where you can store all the application state and the components who need data can subscribe to. You can call fetch just one time maybe in the root component of the app and all 10 instances of your component can subscribe to state.
If you want to avoid using redux or some kind of state management library, you can import a file which does the fetching for you. Something along these lines. Essentially the cache is stored within the fetcher.js file. When you import the file, it's not actually imported as separate code every time, so the cache variable is consistent between imports. On the first request, the cache is set to the Promise; on followup requests the Promise is just returned.
// fetcher.js
let cache = null;
export default function makeRequest() {
if (!cache) {
cache = fetch({
path: '/load/stuff'
});
}
return cache;
}
// index.js
import fetcher from './fetcher.js';
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
loaded: false
stuff: null
};
}
componentDidMount() {
// load stuff
fetcher().then( stuff => {
this.setState({
loaded: true,
stuff: stuff
});
} );
}
render() {
if ( !this.state.loaded ) {
// not loaded yet
return false;
}
// display component based on loaded stuff
return (
<SomeControl>
{ this.state.stuff.map( ( item, index ) =>
<h1>items with stuff</h1>
) }
</SomeControl>
);
}
}
You can use something like the following code to join active requests into one promise:
const f = (cache) => (o) => {
const cached = cache.get(o.path);
if (cached) {
return cached;
}
const p = fetch(o.path).then((result) => {
cache.delete(o.path);
return result;
});
cache.set(o.path, p);
return p;
};
export default f(new Map());//use Map as caching
If you want to simulate the single fetch call with using react only. Then You can use Provider Consumer API from react context API. There you can make only one api call in provider and can use the data in your components.
const YourContext = React.createContext({});//instead of blacnk object you can have array also depending on your data type of response
const { Provider, Consumer } = YourContext
class ProviderComponent extends React.Component {
componentDidMount() {
//make your api call here and and set the value in state
fetch("your/url").then((res) => {
this.setState({
value: res,
})
})
}
render() {
<Provider value={this.state.value}>
{this.props.children}
</Provider>
}
}
export {
Provider,
Consumer,
}
At some top level you can wrap your Page component inside Provider. Like this
<Provider>
<YourParentComponent />
</Provider>
In your components where you want to use your data. You can something like this kind of setup
import { Consumer } from "path to the file having definition of provider and consumer"
<Consumer>
{stuff => <SomeControl>
{ stuff.map( ( item, index ) =>
<h1>items with stuff</h1>
) }
</SomeControl>
}
</Consumer>
The more convenient way is to use some kind of state manager like redux or mobx. You can explore those options also. You can read about Contexts here
link to context react website
Note: This is psuedo code. for exact implementation , refer the link
mentioned above
If your use case suggests that you may have 10 of these components on the page, then I think your second option is the answer - two components. One component for fetching data and rendering children based on the data, and the second component to receive data and render it.
This is the basis for “smart” and “dumb” components. Smart components know how to fetch data and perform operations with those data, while dumb components simply render data given to them. It seems to me that the component you’ve specified above is too smart for its own good.
It's my understanding that the most common use care for iterating over a list of data is map, which is an array method that iterates over an array, but when I tried to apply it here:
import React, { Component } from 'react';
import { View, Text } from 'react-native';
import axios from 'axios';
class QuestionList extends Component {
state = { questions: [] };
componentWillMount() {
axios
.get('https://opentdb.com/api.php?amount=10&difficulty=hard&type=boolean')
.then(response => this.setState({ questions: response.data }));
}
// renderQuestions() {
// return this.state.questions.map(question => <Text>{}</Text>);
// }
render() {
console.log(this.state);
return (
<View>
<Text>{}</Text>
</View>
);
}
}
export default QuestionList;
I ended up getting an error in the Simulator saying that this.state.questions.map() is not a function. I have searched for similar errors online, but they do not apply to my use case.
Keep in mind I commented out the code and erased what I had inside of <Text> because my machine was about to take off.
I don't know what this error means short of not being able to use the map() array helper method, does that mean I need to be applying a different helper method to iterate through this list of questions?
I did a console log of the response object like so:
import React, { Component } from 'react';
import { View, Text } from 'react-native';
import axios from 'axios';
class QuestionList extends Component {
state = { questions: [] };
componentWillMount() {
axios
.get('https://opentdb.com/api.php?amount=10&difficulty=hard&type=boolean')
.then(response => console.log(response));
}
render() {
console.log(this.state);
return (
<View>
<Text>{}</Text>
</View>
);
}
}
export default QuestionList;
and I got back the response object in the console:
from axios with a status of 200 which means the request was successful. You will notice I also go the data property and inside that is the results property and then the category with questions is inside of it:
So I am wondering if its that results property that I need to also implmement, but when I tried it I would get map() undefined.
Your API returns an object, which has no map method.
response.data.results is an array so change it to that if you intend to map over it:
this.setState({ questions: response.data.results }))
It's advisable to use componentDidMount instead of componentWillMount for async update.
I am using React and trying to load data into my component from a local json file. I am trying to print all information, including the 'name' in a name:value pair (not just the value) to make it look like a form.
I am looking for the best way to do this. Do I need to parse? Do I need to use a map function? I am new to React so please show me solution with code. I've seen other questions similar to this but they include a lot of other code that I don't think I need.
Example of my code:
test.json
{"person": {
"name": "John",
"lastname": "Doe",
"interests":
[
"hiking",
"skiing"
],
"age": 40
}}
test.js
import React, {Component} from 'react';
class Test extends Component {
render () {
return (
)
}
};
export default Test;
I need code that lets me import from json and code inside component that displays ALL fields.
If your json is stored locally, you don't have to use any library to get it. Just import it.
import React, {Component} from 'react';
import test from 'test.json';
class Test extends Component {
render () {
const elem = test.person;
return (
<ul>
{Object.keys(elem).map((v, i) => <li key={i}>{v} {test[v]}</li> )}
</ul>
)
}
};
export default Test;
The first important question to care about is how you want to get this JSON, if I understood your problem very well it's a local JSON file. So you need to run a local server inside your app to get these values.
I'd recommend the live-server, made in node.js.
After that you can use axios to fetch data and then ...
import React, {Component} from 'react';
import axios from 'axios';
constructor (props) {
this.state = {
items: [],
}
axios.get('http://localhost:8080/your/dir/test.json')
.then(res => {
this.setState({ items: res.data });
});
}
class Test extends Component {
console.log(this.state.items);
render () {
return (
)
}
};
export default Test;
I've already put a console.log before render to show your object, and after that do whatever you want!
Use JSON.parse(json)
Example:
JSON.parse(`{"person": {
"name": "John",
"lastname": "Doe",
"interests": [
"hiking",
"skiing"
],
"age": 40
}}`);
Hi the best solution to this is using Axios.
https://github.com/mzabriskie/axios
Try look at their API its very straightforward.
And yes, you might need a map function to loop the parsed data.
I have a sample code here, which I used Axios.
import axios from 'axios';
const api_key = 'asda99';
const root_url = `http://api.jsonurl&appid=${api_key}`;
export function fetchData(city) { //export default???
const url = `${root_url}&q=${city},us`;
const request = axios.get(url);
}
request is where you get your parsed data. Go ahead and play with it
Heres another example using ES5
componentDidMount: function() {
var self = this;
this.serverRequest =
axios
.get("http://localhost:8080/api/stocks")
.then(function(result) {
self.setState({
stocks: result.data
});
})
},
by using the 2nd one. you stored the stocks as a state in here. parse the state as pieces of data.
After http://localhost:3001/ you type your directory of JSON file:
Mydata.json is my JSON file name, you type your file name:
Don't forget to import axios on the top. *
componentDidMount() {
axios.get('http://localhost:3001/../static/data/Mydata.json')
.then(response => {
console.log(response.data)
this.setState({lists: response.data})
})
}
If you're loading a file over HTTP, then you can use the built-in window.fetch() function (in browsers for the last few years, see Mozilla's developer pages for compatibility support).
fetch("https://api.example.com/items")
.then(res => res.json())
The React docs explain some other ways of doing Ajax requests (i.e. requests from within an already-loaded web page).
If your JSON is in a local file, then just import it, as others have explained:
import test from 'test.json';