Having error "SyntaxError: Unexpected token < in JSON at position 0” - reactjs

I'm new to React btw, I've been trying to read my test.json file which is located in :
src/data/test.json
My app.js is written as such :
import React, { Component } from 'react';
import './App.css';
var HotelData = require('../data/test.json')
class App extends Component {
constructor(){
super();
this.state = {
data: [],
}
}
getDatafromHotel(){
fetch(HotelData)
.then((Response) => Response.json())
.then((findresponse) => {
console.log(findresponse.data);
this.setState({data: findresponse.data})
})
}
componentDidMount(){
this.getDatafromHotel();
}
render() {
return(
<div className="body">
<div className="container">
{this.state.HotelData.map((hotel) => (
<div className="row">
<div className="col-1">
{hotel.roomTypeLabel}
</div>
<div className="col-2">
</div>
</div>
))}
</div>
</div>
);
}
}
export default App;
Is there any way that I could read test.json file rather than the index.html in the public folder?
test.json file : https://api.myjson.com/bins/16ocrc

You can't use require to import JSON files like you would for javascript ones. Take a look at the fetch api: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch.
As for the code you need to change, it would be:
getDatafromHotel(){
fetch("../data/test.json")
.then((Response) => Response.json())
.then((findresponse) => {
console.log(findresponse.data);
this.setState({data: findresponse.data})
})
Lastly, you need to remove the require statement.

the line:
var HotelData = require('../data/test.json';
should be:
var HotelData = '../data/test.json';
assuming that location is correct and not a 404.

Related

How to access function from different components React

Here's the code for Panel
`
import React from "react";
// import {render} from "react-dom";
import AddInventory from "components/AddInventory";
class Panel extends React.Component{
constructor(props) {
super(props);
this.state = {
activeIndex: ''
}
}
componentDidMount() {
this.activePanel();
}
closePanel=()=>{
this.setState({
activeIndex : false
})
}
activePanel = ()=>{
this.setState({
activeIndex : true
})
}
render(){
return(
<div>
{/*<button className={"button is-primary add-btn"} onClick={this.activePanel}>add</button>*/}
<div className={this.state.activeIndex ? 'panel-wrapper active':'panel-wrapper'}>
<div className={"over-layer"}>
<div className={"panel"}>
<div className={"head"}>
<span onClick={this.closePanel} className={"close"}>x</span>
<AddInventory></AddInventory>
</div>
</div>
</div>
</div>
</div>
)
}
}
export default Panel;
Products:
import React from "react";
import ToolBox from "components/ToolBox";
import Product from "components/Product";
import axios from 'components/axios'
import {CSSTransition , TransitionGroup} from 'react-transition-group'
import Panel from "components/Panel";
class Products extends React.Component{
product =[];
source =[];
state ={
product : [{
id:'1',
name:'Air Jordan1',
tags:'45 colours',
image:'images/1.jpg',
price:'21000',
status:'available'
},
{
id:'2',
name:'Nike Pual George PG 3',
tags:'45 colours',
image:'images/2.jpg',
price:'11000',
status:'available'
},
{
id:'3',
name:'Jordan Why Not Zer0.2',
tags:'10 colours',
image:'images/3.jpg',
price:'15000',
status:'unavailable'
},
]
}
componentDidMount() {
// fetch('http://localhost:3003/products').then(response => response.json()).then( data=>{
// console.log(data)
// this.setState({
// product : data
// })
// })
axios.get('/products').then(response => {
this.setState( {
product : response.data,
source : response.data
})
})
}
search = text=>{
//1.get a new array from product
let _product = [...this.state.source]
//2.filter the array
let res = _product.filter((element)=>{
return element.name.toLowerCase().includes(text.toLowerCase())
})
//set state
this.setState({
product : res
})
}
add = ()=>{
let panel = new Panel(this.props)
panel.activePanel()
}
// add =()=>{
// panel.setState({
// activeIndex : true
// })
// }
render() {
return(
<div>
<ToolBox search={this.search}/>
<div className={'products'}>
<div className="columns is-multiline is-desktop">
<TransitionGroup component={null}>
{
this.state.product.map(p=>{
return (
<CSSTransition
timeout={400}
classNames="product-fade"
key={p.id}
>
<div className="column is-3" key={p.id}>
<Product product={p}/>
</div>
</CSSTransition>
)
})
}</TransitionGroup>
{/*<div className="column is-3">*/}
{/* <Product/>*/}
{/*</div>*/}
{/*<div className="column is-3">*/}
{/* <Product/>*/}
{/*</div>*/}
</div>
<button className={"button is-primary add-btn"} onClick={this.add}></button>
</div>
</div>
)
}
}
export default Products;
I was trynna use activePanel() in Products but it gives me : Warning: Can't call setState on a component that is not yet mounted. This is a no-op, but it might indicate a bug in your application. Instead, assign tothis.statedirectly or define astate = {};` class property with the desired state in the Panel component.
I tried initialize a new panel() but it still gives me the same error.
welcome. I don't think this approach is best practice. Generally, components should only ever be updating their own state (see here) and typically you want data to flow from parent component to child component (see here). Additionally, your design is deceptive. When you render a component, you declare it as JSX in some render (or return) statement. But here, Panel is never formally instantiated in JSX.
In Panel, I would suggest watching a prop such as active via shouldComponentUpdate and updating state based on changes to that prop. Then in Products you can instantiate an instance of Panel in JSX and dynamically set the value of that prop.

ReactJS select value from json array

So I'm trying to get some data from my api and then select that data and send it to the other api, but I can't figure it out how to select the data.
import React, { Component } from 'react'
import Dropdown from 'react-dropdown'
import 'react-dropdown/style.css'
class Testas extends Component {
constructor(props){
super(props);
this.state = {
}
}
componentDidMount() {
const headers = {
'Authorization': 'Bearer ',''
};
fetch(`https://spiceworks/api/printserver/printers`,{ headers }
)
.then(res => res.json())
.then(json => {
this.setState({
isLoaded: true,
items: json.printers,
})
});
}
render() {
const { items } = this.state
const type = ['test', 'python', 'web', 'all']
const amount = [1,2,3,4,5,6,7,8,9,10]
return (
<div className="content">
<form>
<div className="row">
<div className="col-sm">
<div className="card">
<div className="card-body">
<h3 className="card-title">Printer Test</h3>
<Dropdown className="drop" options={this.state.items} placeholder="Pasirinkti printerį" />
<Dropdown className="drop2" options={type} placeholder="Būdas" />
<Dropdown className="drop2" options={amount} placeholder="Kiekis" />
Test
</div>
</div>
</div>
</div>
</form>
</div>
)
}
}
export default Testas
the data I recieve from api looks like this
{
"printers": [
"ZEB-SOFA15",
"ZEB-120",
"GDX-SOFUZ4",]}
i tried with e value onchange code but then I always get error that data.map is not a function.

How to fetch and display image in React, saved in Mongodb as Cloudinary URL

I just started using Cloudinary to upload picture in an application am working on. It is stored in MongoDB database as url link. I have succeeded with the upload. My database looks like this after saving:
id:5f90315331dc1727bc869afe
userEmail:"fletcher#gmail.com"
image:"https://res.cloudinary.com/myapp/image/upload/v1603285331/ifyo38crk..."
imageId:"ifyo38crkdniixeimme9"
__v:0
My get() endpoint looks like this :
app.get("/getAvatar/:email", (req, res) => {
userEmail= req.params.email;
Image.find({userEmail:userEmail},(err, images)=> {
if (err) {
res.status(500);
res.send(err);
} else {
res.json(images);
}
});
});
and my React front-end :
class AllImages extends Component {
componentDidMount(){
const{user}=this.props.auth
const email = user.email
this.props.getAvatar(email)
}
render() {
return this.props.resumeData.map(image=>{
return(
<div className="image-card-container">
<div key={image.id} className='image-card'>
<h4>{image.userEmail}</h4>
<img
className='main-image'
src={image.image}
alt='profile image'
/>
</div>
</div>
)
Redux action :
export const getAvatar=(email)=>dispatch=>{
dispatch(AvatarLoading());
axios.post('/getAvatar/'+ email )
.then(res=>
dispatch({
type: GET_RESUME_AVATAR,
payload: res.data
})
)
history.push('/');
};
On componentMount() i get the error :
TypeError: Cannot read property 'map' of undefined
something is definitely wrong with my code. This is my first time of working with Cloudinary, I will appreciate if anyone can help out!
Add a null check inside render()
class AllImages extends Component {
componentDidMount(){
const{user}=this.props.auth
const email = user.email
this.props.getAvatar(email)
}
render() {
return (
<div>
{this.props.resumeData && this.props.resumeData.map(image=>{
return(
<div className="image-card-container">
<div key={image.id} className='image-card'>
<h4>{image.userEmail}</h4>
<img
className='main-image'
src={image.image}
alt='profile image'
/>
</div>
</div>
)}
</div>
)
}
The render will get executed before componentDidMount and re-rendered on prop change.

Updating one value in an object of arrays

I have an array containing objects with details for an image (URL, description, likes) I'm trying to clone an Instagram page, and update the "likes" for that 1 image on click.
Attempted to map through the array and return with the "likes" + 1.
Here are 3 separate files starting with the data. The data is stored in the "Main" section in the state Gallery. So to overview, I want to increase the number of likes when I click on that image. But when I setState, I have no idea how I can only target one value in one object of the array. I would rather just update the state rather than create a new state onClick and then change the value that was! I'm looking for the best practice. (as this is the only way I can learn) Thanks in advance.
const images =[
{
url:'./images/img1.jpg',
description:"test1",
likes:0,
index:0
},
{
url:'./images/img2.jpg',
description:"test1",
likes:3,
index:1
},
{
url:'./images/img3.jpg',
description:"test1",
likes:4,
index:2
},
{
url:'./images/img2.jpg',
description:"test1"
},
{
url:'./images/img2.jpg',
description:"test1"
},
{
url:'./images/img2.jpg',
description:"test1"
},
]
export default images
import React from 'react'
const Gallery =(props)=>{
return (
<div className="container">
<div className="main-gallery">
{props.gallery.map((item,index) => (
<div key={index} className='img-container' onClick= {props.increaseLikes}>
<img className='gallery-images' src={item.url}/>
<p className='likes'>likes {item.likes}</p>
</div>
))}
</div>
</div>
)
}
export default Gallery
import React, { Component } from "react";
import ReactDOM from 'react-dom';
import Nav from './Components/Navbar/Nav'
import Header from './Components/Header/Header'
import Carousel from './Components/Carousel/Carousel'
import Data from './Data'
import Gallery from './Components/Gallery/Gallery'
class Main extends Component {
constructor(props) {
super(props);
this.state={
post:100,
gallery:[],
}
}
componentDidMount(){
this.setState({
gallery:Data
})
}
increaseLikes=()=>{
//no idea how to update
}
render() {
return (
<div>
<Gallery gallery={this.state.gallery} increaseLikes= {this.increaseLikes}/>
</div>
)
}
}
export default Main;
Your increaseLikes function needs to get id of the image from the Gallery component.
So the code must be like something like this:
I assumed your data has an unique id property.
increaseLikes = id => {
const updatedData = this.state.gallery.map(image => {
if (image.id === id) {
return { ...image, likes: image.likes ? image.likes + 1 : 1 };
} else {
return image;
}
});
this.setState({
gallery: updatedData
})
};
Gallery component code:
import React from "react";
const Gallery = props => {
return (
<div className="container">
<div className="main-gallery">
{props.gallery.map((item, index) => (
<div
key={item.id}
className="img-container"
onClick={() => props.increaseLikes(item.id)}
>
<img
className="gallery-images"
src={item.url}
alt={item.description}
/>
<p className="likes">likes {item.likes ? item.likes : 0} </p>
<hr />
</div>
))}
</div>
</div>
);
};
export default Gallery;
you could use the url (That seems to be the only unique value) of the images in order to update your array, I've made a StackBlitz where you can see how to do it. Hope this helps.

How to print list output dynamically in React JS as buttons

Below is the code snippet of my ReactJS component, I'm trying to put the output with a button beside it in a list format. The output which is received in the "axios" get function is from an api and it is in this format: [{'name': 'i-cc608f4d'}, {'name': 'i-fd608f7c'}, {'name': 'i-fe608f7f'}]
I want to list these IDs with a button besides it.
import React, { Component } from "react";
import axios from "axios";
const pStyle = {
backgroundColor: "#79D3EF",
color: "white"
};
export default class CityContent extends Component {
constructor(props) {
super(props);
this.state = {
citydetail: []
};
}
componentDidMount() {
axios.get("http://127.0.0.1:8000/Delhi").then(res => {
const citydetail = res.data;
this.setState({ citydetail });
});
}
render() {
return (
<div className="content-wrapper">
<section className="content-header">
<div className="row">
<div className="col-md-4">
<div className="box">
<div className="box-body">
<div className="row">
<div className="col-md-8">
<ul>{this.state.citydetail.state}</ul>
</div>
</div>
</div>
</div>
</div>
</section>
</div>
);
}
What should I write to replace {this.state.citydetail.state}.
Because currently, it's printing the API output itself.
<div className="col-md-8">
<ul>
{
this.state.citydetail.map((city) => (
<li>{city.name}<button>Click</button></li>
)}
</ul>
</div>
This code will print your output and map will map through that data of citydetail and button beside it.
It should be something like this
<ul>
{
this.state.citydetail.map((city, index) => (
<li key={index}>{city.name}<button>{city.name}</button></li>
)}
</ul>
Update
Set your state like this in componentDidMount()
this.setState({ citydetail : citydetail });
Update 2 (after OP comment)
I cannot change the format of this output...
try this
axios.get("http://127.0.0.1:8000/Delhi").then(res => {
const citydetail = res.data;
let arrData = JSON.parse(citydetail.replace(/'/g, '"'));
this.setState({ citydetail: arrData });
});

Resources