Local JSON file is not parsing in React - javascript

I have a large JSON file which has around 5000 entries and when I parse it using fetch(), it doesn't show up in browser.
Here's my code:
import React from 'react';
import './Box.css';
class Box extends React.Component {
constructor() {
super()
this.state = {movieName: []}
}
componentDidMount() {
fetch('./MovieDatabaseShort.json')
.then(a => a.json())
.then(movieName => this.setState({movieName}));
}
renderMovies() {
const { movieName } = this.state;
return movieName.map(a => {
<h1 key={ a.id } className='heading'>{a.title}</h1>;
});
}
render() {
return <div className="box">{this.renderMovies()}</div>;
}
}
export default Box;
I just want to put all the movies titles.
import React from 'react';
import './Box.css';
class Box extends React.Component {
constructor() {
super()
this.state = {movieName: []}
}
componentDidMount() {
fetch('https://support.oneskyapp.com/hc/en-us/article_attachments/202761627/example_1.json')
.then(a => a.json())
.then(movieName => this.setState({movieName: movieName.color}));
}
render() {
console.log( this.state );
return <div className="box">{this.state.movieName}</div>;
}
}
export default Box;
EDIT- In second code, I just copied random json file from net and it works fine. I think its's due to size of the json file I have. It's 250k+ lines.
Update- This works. I think problem is due to fetch()
import React from 'react';
import './Box.css';
import a from './MovieDatabaseShort.json'
class Box extends React.Component {
constructor() {
super()
this.state = {movieName: []}
}
componentDidMount() {
this.setState({movieName: a});
}
renderBox() {
const { movieName } = this.state;
return movieName.map(k => {
return <h1 className='heading'>{k.title}</h1>;
})
}
render() {
return (
<div className='box'>{this.renderBox()}</div>
);
}
}
export default Box;`

First of all, there are some places you should change in your code.
You should keep an array property in your state for all movies: movies: []
You should map this state value, then render some JSX.
Use componentDidMount instead of componentWillMount since it will be deprecated in a future release.
Here is the example code:
class Box extends React.Component {
constructor() {
super();
this.state = { movies: [] };
}
componentDidMount() {
fetch("./MovieDatabaseShort.json")
.then(res => res.json())
.then(movies => this.setState({ movies }));
}
renderMovies() {
const { movies } = this.state;
return movies.map(movie => (
<h1 key={movie.title} className="heading">
{movie.title}
</h1>
));
}
render() {
return <div className="box">{this.renderMovies()}</div>;
}
}
If you still don't see anything maybe fetch would the problem here. Then, try this:
class Box extends React.Component {
constructor() {
super();
this.state = { movies: [] };
}
componentDidMount() {
import("./MovieDatabaseShort.json").then(movies =>
this.setState({ movies })
);
}
renderMovies() {
const { movies } = this.state;
return movies.map(movie => (
<h1 key={movie.title} className="heading">
{movie.title}
</h1>
));
}
render() {
return <div className="box">{this.renderMovies()}</div>;
}
}
Again, if nothing is shown up please share you JSON file with us as well as check your console if there is any error.

What it looks like you want to do is to save all movies into an array on your state. That would look more like this:
constructor() {
super()
this.state = {movies: []}
}
componentWillMount() {
fetch('./MovieDatabaseShort.json')
.then(a => a.json())
.then(b => this.setState({movies: b}));
}
Then in your render function you would loop over your movies and display the title:
render() {
const { movies } = this.state;
return (
<div className='box'>
{movies.map(movie => <h1 className='heading'>{movie.title}</h1>)}
</div>
);
}

Another way using hook can be the following. In my case I need to take configuration data from a json file
import _data from '../../json/config.json';
export const Mapa = () => {
const [config, setConfig] = useState(null);
useEffect(()=>{
setConfig(_data );
},[]);
}

Related

why using map is giving me the error( .map is not a function),it seems everything is ok in my code?

Since i am new on React JS,i tried to use map function but it gives me the following error:Uncaught TypeError: totalData.map is not a function.It seems everything is ok in the code,please provide me some feedback.Following below is my codes:
import React, { Component } from 'react';
import axios from 'axios';
export default class TotalData extends Component {
constructor() {
super();
this.state = {
totalData: [],
isfinalData: false
}
}
componentDidMount() {
axios.get('https://nepalcorona.info/api/v1/data/nepal')
.then(res => {
this.setState({
totalData: res.data,
isfinalData: true
})
})
}
render() {
console.log("final data>>", this.state);
const { totalData, isfinalData } = this.state;
let finalData = isfinalData
? totalData.map((item, deaths) => (
<div>
<p>{item.deaths}</p>
</div>
))
: <p>Isloading</p>
return (
<div>
{finalData}
</div>
)
}
}
what may be the issue on my code ?
Following below are my fetched data from API and error i got:
import React, { Component } from 'react'
import axios from 'axios'
export default class App extends Component {
constructor() {
super()
this.state = {
totalData: [],
isfinalData: false
}
}
componentDidMount() {
axios.get('https://nepalcorona.info/api/v1/data/nepal').then((res) => {
this.setState({
totalData: res.data,
isfinalData: true
})
})
}
render() {
console.log('final data>>', this.state)
const { totalData, isfinalData } = this.state
let finalData = isfinalData ? (
<div>
<p>{totalData.deaths}</p>
</div>
) : (
<p>Isloading</p>
)
return <div>{finalData}</div>
}
}
you don't need to use map because you have only one object

Dog API breeds return undefined 404 error React.js

I'm trying to get the specific photos that belong to a dog breed when a user clicks on a breed (for instance, they click on "hound" and then the photos of 3 random hounds appear). I continue to receive GET https://dog.ceo/api/breed/undefined/images/random/3 404 (404 error and returning undefined inside of the fetch url) in the dev tools when clicking on the specific breed. When I console.log breedName inside of getSelectedBreed, it comes back as the specific breed that the user clicked on however, once the interpreter gets to the method, selectBreed, the console.log returns undefined.
Here is my code for my App component and Breeds component, thank you!
App component:
import React, { Component } from 'react';
import './App.css';
import Header from '../Header/Header';
import Breeds from '../Breeds/Breeds';
class App extends Component {
constructor() {
super();
this.state = {
breedName: '',
breeds: [],
hasErrors : false
}
}
getSelectedBreed = (breedName) => {
this.setState({
breedName: breedName,
})
this.selectBreed();
}
selectBreed = (breedName) => {
console.log('breedName:', breedName)
fetch(`https://dog.ceo/api/breed/${breedName}/images/random/3`)
.then(res => res.json())
.then(breed => this.setState({ getSelectedBreed: breed.breedName }))
.catch(() => this.setState({ hasErrors: true }))
}
componentDidMount() {
const breedUrl = 'https://dog.ceo/api/breeds/list/all'
fetch(breedUrl)
.then(res => res.json())
.then(data => this.setState({breeds: data.message}))
.catch(() => this.setState({ hasErrors: true }))
}
render() {
console.log('breed', this.state.breedName)
return (
<div>
<Header />
<Breeds
breeds={this.state.breeds}
getSelectedBreed={this.getSelectedBreed}
/>
</div>
)
}
}
export default App;
and Breeds component:
import React, {Component} from 'react';
import './Breeds.css';
class Breeds extends Component {
constructor(props) {
super(props);
this.state={
}
}
render() {
const listOfBreeds = Object.keys(this.props.breeds)
const breedItems = listOfBreeds.map((breedName, index) =>
<div key={index}>
<div onClick={()=>this.props.getSelectedBreed(breedName)}>
<p className='breed-name' onClick={()=>this.props.getSelectedBreed(breedName)}>{breedName}</p>
</div>
</div>
)
return (
<div>
<div className='breed-container'>{breedItems}</div>
</div>
);
}
}
export default Breeds;
Looks like you forgot to pass bread name in selectBreed method.
getSelectedBreed = (breedName) => {
this.setState({
breedName: breedName,
})
this.selectBreed(breedName); //Missing breedName in your code
}

Why React doesn't render my result after setState?

Having the below jsx code:
import React, { Component } from 'react';
import RemoteAssets from '../modules/RemoteAssets';
class RemoteOptions extends Component {
constructor(props) {
super(props);
this.state = {
RemoteOptions: []
}
}
componentDidMount() {
const { api, locale } = this.props;
RemoteAssets.loadRemoteOptions({ api, locale }).then((RemoteOptions) => {
console.log( 'RemoteOptions', RemoteOptions);
this.setState((state, props) => ({
RemoteOptions
}), () => {
this.render()
});
})
}
render() {
return (
<div className="row">
<div className="col-4">
<label >Opt: </label>
</div>
<div className=" col-8">
{JSON.stringify(this.state.RemoteOptions)}
</div>
</div>
);
}
}
export default RemoteOptions;
This is what happens to me:
componentDidMount logs correctly the payload expected.
console.log( 'RemoteOptions', RemoteOptions);
So I believe that It will also set State as expected:
this.setState((state, props) => ({
RemoteOptions
}), () => {
this.render()
});
I also added above a this.render() stmt to be sure the component will be re-rendered after updating the state.
But :
{JSON.stringify(this.state.RemoteOptions)}
Will always return "[]" as the init state before componentDidMount happens and update the state.
How should I arrange this component to have my render update the with the payĆ²oad loaded async?
Name conflict
Your state name and class name are in conflict.
class RemoteOptions extends Component { // class name
constructor(props) {
super(props);
this.state = {
RemoteOptions: [] // state name
}
}
...
Call your state something different.
Why not simply using setState the way documentation suggests?
this.setState({ RemoteOptions });
Render method will be automatically called right after the state is set.
I implemented the skeleton of the problem, and everything works as expected.
const loadRemoteOptions = () => new Promise(resolve => {
setTimeout(() => resolve('myRemoteOptions'), 1000)
})
class App extends React.Component {
state = {
remoteOptions: null
}
componentDidMount(){
loadRemoteOptions().then(remoteOptions => this.setState({ remoteOptions }))
}
render(){
return this.state.remoteOptions || 'Loading...';
}
}
ReactDOM.render(<App />, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>

Cannot read property 'toLowerCase' of undefined - REACT - FIRESTORE

I'm a bit new to React and Firestore and already trying to figure out what is happening for a couple of hours. I Try to make my filter function working with data which I receive from Firestore in APP.js. I pass the data {tasks, searchTerm} to DASHBOARD component. The filter worked before when using state and props, but after replacing the hard-coded data in state with firestore data, it doesn't work anymore and I get the following error when filtering the array in the DASHBOARD component:
Cannot read property 'toLowerCase' of undefined
I've tried to send the data without any filtering directly to TASKS.js and this is working correctly (all the tasks are shown). But as soon as I pass newArray to , it doesn't work anymore.
Also, when logging task.title in tasks.filter function in the DASHBOARD component, it shows all the data (with a little delay because the data is coming from Firestore)
APP.JS -
import React, { Component } from 'react';
import './App.css';
import Dashboard from './Components/Dashboard/Dashboard'
import AddTask from './Components/Tasks/Task/AddTask'
import Navbar from './Components/Navbar/Navbar'
import Searchbar from './Components/Searchbar/Searchbar'
import firebase from './Firebase';
class App extends Component {
constructor(props) {
super(props)
this.ref = firebase.firestore().collection('tasks')
this.state = {
tasks: [],
searchTerm: ""
}
this.handleLikeButton = this.handleLikeButton.bind(this)
this.handleRemoveButton = this.handleRemoveButton.bind(this)
this.addTask = this.addTask.bind(this)
this.handleFilter = this.handleFilter.bind(this)
}
componentWillMount() {
const db = firebase.firestore()
const allTasks = []
db.collection('tasks').onSnapshot(collection => {
const tasks = collection .docs.map(doc => doc.data())
this.setState({ tasks: tasks, searchTerm: "" })
})
}
handleLikeButton = (task) => (e) => {
const tasks = [...this.state.tasks]
const index = tasks.indexOf(task)
tasks[index].likes++
this.setState({
tasks: tasks
})
}
addTask = (taskName) => (e) => {
this.ref.add({
id: Math.floor(Math.random() * 100000000000000),
title: taskName,
likes: 0
})
}
handleRemoveButton = (removingTask) => (e) => {
const tasks = [...this.state.tasks]
const newTasks = tasks.filter(task => removingTask.id !== task.id)
this.setState({
tasks: newTasks
})
}
handleFilter = (searchTerm) => {
this.setState({
searchTerm: searchTerm
})
}
render() {
return (
<div className="App">
<Navbar />
<Searchbar handleFilter={this.handleFilter} />
<AddTask addTask={this.addTask} />
<Dashboard tasks={this.state.tasks} searchTerm={this.state.searchTerm} handleLikeButton={this.handleLikeButton} handleRemoveButton={this.handleRemoveButton}/>
</div>
);
}
}
export default App;
DASHBOARD.JS -
import React, { Component } from 'react'
import Tasks from '../Tasks/Tasks'
class Dashboard extends Component {
constructor(props) {
super(props)
this.filterTasks = this.filterTasks.bind(this)
}
filterTasks = () => {
const tasks = [...this.props.tasks]
const newArray = tasks.filter(task =>
task.title.toLowerCase().indexOf(this.props.searchTerm.toLowerCase()) > -1)
return (
<Tasks tasks={newArray} handleLikeButton={this.props.handleLikeButton} handleRemoveButton={this.props.handleRemoveButton} />
)
}
render() {
return (
<div>
<h2>Dashboard</h2>
{this.filterTasks()}
</div>
)
}
}
export default Dashboard
ADDTASK.JS
import React, { Component } from 'react'
class AddTask extends Component {
constructor(props) {
super(props)
this.state = {
addNewTaskFieldEmpty: true,
taskName: ""
}
this.onChangeHandler = this.onChangeHandler.bind(this)
this.disableButton = this.disableButton.bind(this)
}
onChangeHandler(e) {
this.setState({
taskName: e.target.value,
})
this.disableButton(e.target.value)
}
disableButton(taskName) {
if(taskName.length == 0) {
this.setState({addNewTaskFieldEmpty: true})
} else {
this.setState({addNewTaskFieldEmpty: false})
}
}
render() {
return (
<div>
<div className="mdc-text-field half-size">
<input className="mdc-text-field__input " onChange={this.onChangeHandler} />
<div className="mdc-line-ripple"></div>
<label className="mdc-floating-label">Task Name</label>
</div>
<a className={"btn-floating btn-large waves-effect waves-light red " + (this.state.addNewTaskFieldEmpty ? 'disabled' : '')} onClick={this.props.addTask(this.state.taskName)}><i className="material-icons">add</i></a>
</div>
)
}
}
export default AddTask
Lint your App.css for any errors.
I encountered this message. I traced it to a CSS include:
.box-table { border-color:; border: 1px solid #dbdad8; }
The missing value of border-color: caused npm run build to fail.
Interestingly, the same file contained
.submenu-button.submenu-opened:after { background:; }
which caused no problems at all.

Re-render component with componentWillReceiveProps?

I have a .jsx with a parent class and a child, in the parent i initialize the api and stock the json content in a state:
constructor(props) {
super(props);
this.state = {
all: '',
};
}
componentDidMount() {
this.loadApi();
}
loadApi(){
this.setState({ all: myApiGet('https://********') });
}
After that i need to get the "url" of the differents pics for show them on the site. But there is the problem, I get the api json when i load the page and i don't success to re-load the function.
componentWillReceiveProps(nextProps) {
this.apiGetProductPicture(nextProps.categorie);
}
apiGetProductPicture = (i) => () => {
// TODO do something with the data
var stock = this.props.all
.then(stock => this.setState({ pictures: stock.content.categories[i].background }))
.catch(error => console.log('home2', error));
}
I try a lot of possibility and check the net but the solution doesn't work for me (or i just doesn't understand them ...)
Thanks for your time :/
Full component:
class ProductItem extends React.Component {
constructor(props) {
super(props);
this.state = {
pictures: '',
name: '',
price: '',
json: '',
};
//this.apiGetProductPicture = this.apiGetProductPicture.bind(this);
}
componentWillReceiveProps(nextProps) {
this.apiGetProductPicture(nextProps.categorie);
}
apiGetProductPicture = (i) => () => {
// TODO do something with the data
var stock = this.props.all
.then(stock => this.setState({ pictures: stock.content.categories[i].background }))
.catch(error => console.log('home2', error));
}
render() {
return (
......
)
}
}
Error message:
The above error occurred in the component:
in ProductItem (created by Home2)
in div (created by Home2)
in div (created by Home2)
in div (created by Home2)
in div (created by Home2)
in main (created by Home2)
in Home2
Consider adding an error boundary to your tree to customize error handling behavior.
You can learn more about error boundaries at https:// fb.me/react-error-boundaries.
react-dom.development.js:9312:5
ReferenceError: props is not defined
Ok i think i see some changes to be made
in your parent component your setting this.state.all to be a promise (the promise returned from your api call)
let's change that to be the actual json from your api call
Parent component:
constructor(props) {
super(props);
this.state = {
all: '',
};
this.loadApi = this.loadApi.bind(this);
}
componentDidMount() {
this.loadApi();
}
loadApi() {
myApiGet('https://********')
.then(all => this.setState({ all }));
}
Child Component:
class ProductItem extends React.Component {
constructor(props) {
super(props);
this.state = {
pictures: '',
name: '',
price: '',
json: '',
};
this.apiGetProductPicture = this.apiGetProductPicture.bind(this);
}
ComponetDidMount() {
apiGetProductPicture(this.props.categorie);
}
componentWillReceiveProps(nextProps) {
if (nextProps.categorie !== this.props.categorie)
{
this.apiGetProductPicture(nextProps.categorie);
}
}
apiGetProductPicture(categorie) {
// TODO do something with the data
if (!this.props.all) return;
var categories = (((this.props.all || {}).stock || {}).content || {}).categories;
if (categories.indexOf(categorie) > -1)
{
this.setState({ pictures: categories[categorie].background }));
}
}
render() {
return (
......
);
}
}
Thanks for your time :/
no worries :)
i se you posted "Lost in the javascriptception"
this and other questions have provided me with enough info to solve your problem, sorry the stackoverflow community was so mean to you, but not all of us are like that.
I would recommend in the future you post more info on your questions, like full code (except sensible stuff), not just parts, the codesanbox was the thing that let me test code and see where the problem was.
Also i f*** up on some of the previous answer, but to be fair i had very limited info to go along with, and most people answering won't test the code for tipos or stuff
version One
import React from "react";
import { render } from "react-dom";
import Hello from "./Hello";
const styles = {
fontFamily: "sans-serif",
textAlign: "center"
};
class ProductItem extends React.Component {
constructor(props) {
super(props);
this.state = {
pictures: '',
name: '',
price: '',
json: '',
};
this.apiGetProductPicture = this.apiGetProductPicture.bind(this);
}
componentDidMount() {
this.apiGetProductPicture(this.props.categorie);
}
componentWillReceiveProps(nextProps) {
this.apiGetProductPicture(nextProps.categorie);
}
apiGetProductPicture(categorie) {
// TODO do something with the data
var categories = this.props.send;
categorie = parseInt(categorie, 10);
if (categorie < categories.length) {
console.log(categories[categorie].background);
this.setState({ pictures: categories[categorie].background });
}
}
render() {
return (
<div>
<p>{this.props.name}</p>
<img src={this.state.pictures} />
</div>
);
}
}
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
all: "",
categories: []
};
this.loadAPI = this.loadAPI.bind(this);
}
componentDidMount() {
this.loadAPI();
}
loadAPI() {
var test = fetch("https:*******")
.then(test => test.json())
.then(testJson => {
// alert(testJson.content.categories[0].description)
var obs = testJson.content.categories.slice();
// alert(testJson);
this.setState({ categories: obs });
});
}
render() {
return (
<div style={styles}>
<Hello name="CodeSandbox" />
<h1>Products</h1>
{this.state.categories.map( (value, i) => {
return <ProductItem
key={value.uid}
send={this.state.categories}
name={value.description}
categorie={i} />
})}
<h2>Start editing to see some magic happen {"\u2728"}</h2>
</div>
);
}
}
render(<App />, document.getElementById("root"));
My recommended Version
import React from "react";
import { render } from "react-dom";
import Hello from "./Hello";
const styles = {
fontFamily: "sans-serif",
textAlign: "center"
};
class ProductItem extends React.Component {
render() {
return (
<div>
<p>{this.props.name}</p>
<img src={this.props.picture} />
</div>
);
}
}
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
all: "",
categories: []
};
this.loadAPI = this.loadAPI.bind(this);
}
componentDidMount() {
this.loadAPI();
}
loadAPI() {
var test = fetch("https:*****")
.then(test => test.json())
.then(testJson => {
// alert(testJson.content.categories[0].description)
var obs = testJson.content.categories.slice();
// alert(testJson);
this.setState({ categories: obs });
});
}
render() {
return (
<div style={styles}>
<Hello name="CodeSandbox" />
<h1>Products</h1>
{this.state.categories.map( (value, i) => {
return <ProductItem
key={value.uid}
picture={value.background}
name={value.description}
categorie={i} />
})}
<h2>Start editing to see some magic happen {"\u2728"}</h2>
</div>
);
}
}
render(<App />, document.getElementById("root"));
Hope this helps you out, don't be so hard on yourself, you know practice makes perfect, also would recommend you follow the react tutorial, to see what react is about, i can seam super hard and weird because it maybe a completely different programming model (it was for me), but when it click it's really cool

Categories