Why I have got an empty object from my context? - javascript

I have a context and try to pass it to my children components:
const PatientContext = createContext([{}]);
function App() {
const [selectedPatient, setSelectedPatient] = useState([]);
const [patients, setPatients] = useState([{ name: 'Taras', age: 19 }, { name: 'Taras', age: 19 }, { name: 'Taras', age: 19 }]);
async function patientsHasChanged() {
const patientService = new PatientService();
const loadedPatients = await patientService.getPatients();
setPatients(loadedPatients);
};
return (
<div className='app'>
<PatientContext.Provider value={[selectedPatient, setSelectedPatient, patients, patientsHasChanged]}>
<Sidebar />
<Content />
</PatientContext.Provider>
</div>
);
}
But if I try use it in my child components I am always getting empty object, how i can fix it?
img with my problem here
UPD:
Here's my component with using context:
const Sidebar = (props) => {
const [patients, selectedPatient, setSelectedPatient] = useContext(PatientContext);
return (
<div className='sidebar'>
<div className='search'>
<input type="text" placeholder='Search' />
<button>New patient</button>
</div>
<div className='list'>
<ul>
{patients.map((p) =>
<li onClick={setSelectedPatient}>
<div className='name'>
{p.name}
</div>
<div className='age'>
{p.age}
</div>
</li>)
}
</ul>
</div>
</div>
);
};

Your problem is you're using an array ([]) for the context; arrays have a given order. You pass in [selectedPatient, setSelectedPatient, patients, patientsHasChanged], and you're unpacking things in a different order ([patients, selectedPatient, setSelectedPatient]), so you get the "wrong" objects.
Instead, use an object ({}) so you can unpack it as you like, and remember to memoize the context value to avoid unnecessary rerenders.
const PatientContext = React.createContext(null);
const Sidebar = (props) => {
const { patients, selectedPatient, setSelectedPatient } = React.useContext(PatientContext);
return (
<div className="sidebar">
<div className="search">
<input type="text" placeholder="Search" />
<a href="/TechTask/new">
<button>New patient</button>
</a>
</div>
<div className="list">
<ul>
{patients.map((p) => (
<li onClick={setSelectedPatient}>
<div className="name">{p.name}</div>
<div className="age">{p.age}</div>
</li>
))}
</ul>
</div>
</div>
);
};
function App() {
const [selectedPatient, setSelectedPatient] = React.useState([]);
const [patients, setPatients] = React.useState([
{ name: "Taras", age: 19 },
{ name: "Taras", age: 19 },
{ name: "Taras", age: 19 },
]);
function patientsHasChanged() {/* elided since SO doesn't support async */}
const patientContext = React.useMemo(() => ({ selectedPatient, setSelectedPatient, patients, patientsHasChanged }), [
selectedPatient,
setSelectedPatient,
patients,
patientsHasChanged,
]);
return (
<div className="app">
<PatientContext.Provider value={patientContext}>
<Sidebar />
</PatientContext.Provider>
</div>
);
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.0/umd/react-dom.production.min.js"></script>
<div id="root"></div>

Related

How to map through data coming from smart contract

So I'm reading data from a smart contract and trying to map through it to display on a frontend but it keeps returning an error
data is undefined
I'll post my code below, I'm really looking forward to some help
import React , { useState , useEffect , Fragment } from 'react';
import {Link} from 'react-router-dom';
import { Tab, Tabs, TabList, TabPanel } from 'react-tabs';
import 'react-tabs/style/react-tabs.css';
import CardModal from '../CardModal';
import MarketplaceJSON from "../../../Marketplace.json";
import axios from "axios";
const TodayPicks = () => {
const [dataTab] = useState(
[
{
id: 1,
title: "All",
},
]
)
const [visible , setVisible] = useState(8);
const showMoreItems = () => {
setVisible((prevValue) => prevValue + 4);
}
const [modalShow, setModalShow] = useState(false);
const [data, updateData] = useState();
const [dataFetched, updateFetched] = useState(false);
async function getAllNFTs() {
const ethers = require("ethers");
//After adding your Hardhat network to your metamask, this code will get providers and signers
const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner();
//Pull the deployed contract instance
let contract = new ethers.Contract(MarketplaceJSON.address, MarketplaceJSON.abi, signer)
//create an NFT Token
let transaction = await contract.getAllNFTs()
//Fetch all the details of every NFT from the contract and display
const items = await Promise.all(transaction.map(async i => {
const tokenURI = await contract.tokenURI(i.tokenId);
let meta = await axios.get(tokenURI);
meta = meta.data;
let price = ethers.utils.formatUnits(i.price.toString(), 'ether');
let item = {
price,
tokenId: i.tokenId.toNumber(),
seller: i.seller,
owner: i.owner,
image: meta.image,
name: meta.name,
description: meta.description,
}
return item;
}))
updateFetched(true);
updateData(items);
}
if(!dataFetched)
getAllNFTs();
console.log(data);
return (
<Fragment>
<div className="tf-section sc-explore-2">
<div className="themesflat-container">
<div className="row">
<div className="col-md-12">
<div className="seclect-box style3">
<div id="artworks" className="dropdown">
<Link to="#" className="btn-selector nolink">All Artworks</Link>
<ul>
<li><span>Abstraction</span></li>
<li className="active"><span>Skecthify</span></li>
<li><span>Patternlicious</span></li>
<li><span>Virtuland</span></li>
<li><span>Papercut</span></li>
</ul>
</div>
<div id="sort-by" className="dropdown style-2">
<Link to="#" className="btn-selector nolink">Sort by</Link>
<ul>
<li><span>Top rate</span></li>
<li className="active"><span>Mid rate</span></li>
<li><span>Low rate</span></li>
</ul>
</div>
</div>
<div className="flat-tabs explore-tab">
<Tabs >
<TabList>
{
dataTab.map(data=> (
<Tab key={data.id} >{data.title}</Tab>
))
}
</TabList>
{
data.map(data =>(
<TabPanel key={data.tokenId}>
{
<div key={data.tokenId} className={`sc-card-product explode style2 mg-bt ${item.feature ? 'comingsoon' : '' } `}>
<div className="card-media">data
<Link to="/item-details-01"><img src={item.img} alt="Axies" /></Link>
<div className="button-place-bid">
<button onClick={() => setModalShow(true)} className="sc-button style-place-bid style bag fl-button pri-3"><span>Place Bid</span></button>
</div>
<Link to="/login" className="wishlist-button heart"><span className="number-like">{item.wishlist}</span></Link>
<div className="coming-soon">{data.feature}</div>
</div>
<div className="card-title">
<h5><Link to="/item-details-01">"{data.title}"</Link></h5>
</div>
<div className="meta-info">
<div className="author">
<div className="avatar">
<img src={data.imgAuthor} alt="Axies" />
</div>
<div className="info">
<span>Creator</span>
<h6> <Link to="/authors-02">{data.nameAuthor}</Link> </h6>
</div>
</div>
<div className="tags">{data.tags}</div>
</div>
<div className="card-bottom style-explode">
<div className="price">
<span>Current Bid</span>
<div className="price-details">
<h5>{data.price}</h5>
<span>= {data.priceChange}</span>
</div>
</div>
<Link to="/activity-01" className="view-history reload">View History</Link>
</div>
</div>
}
{
visible < data.length &&
<div className="col-md-12 wrap-inner load-more text-center">
<Link to="#" id="load-more" className="sc-button loadmore fl-button pri-3" onClick={showMoreItems}><span>Load More</span></Link>
</div>
}
</TabPanel>
))
}
</Tabs>
</div>
</div>
</div>
</div>
</div>
<CardModal
show={modalShow}
onHide={() => setModalShow(false)}
/>
</Fragment>
);
}
export default TodayPicks;
I was also thinking about creating a custom NFT card component to map through but does that work? Please help
You are using Array.map in data and you are not initialising it with [], so on initial load it shows data is undefined error . So Initialise data with [] in useState..
const [data, updateData] = useState([])

axios doesnt fetch on refresh, only on first render

So I've been struggling for a while with retrieving data from APIs and or retrieving local json files. I am using React axios but even with the normal fetch method I am having the same issues. When I fetch the endpoint and save the code, my jsx refreshes and the data appears on the screen but then when I refresh the page, it's no longer there and doesn't appear when I refresh again and again. I have no idea what I am doing wrong. I tried to retrieve the data on the parent and set it as props but still the same problem.
My child component:
import React, { useEffect, useState } from 'react';
import './Card.scss';
import axios from 'axios';
import { ellipsisIcon } from '../../constants/images';
import dataJson from './data.json';
const Card = ({ name, color, icon, currentTime }) => {
const [data, setData] = useState([]);
const [daily, setDaily] = useState([]);
const [weekly, setWeekly] = useState([]);
const [monthly, setMonthly] = useState([]);
useEffect(() => {
const fetchData = async () => {
const result = await axios.get('data.json');
setData(result.data);
setData(
data.filter((item) => {
return item.title === name;
}),
);
setDaily(data[0].timeframes.daily);
setWeekly(data[0].timeframes.weekly);
setMonthly(data[0].timeframes.monthly);
};
fetchData();
}, []);
return (
<div className="card" style={{ backgroundColor: `${color}` }}>
<img src={icon} alt={`${name} icon`} />
<div className="card__container bg-blue">
<div className="card__top-container flex">
<p className="text-white ">{name}</p>
<div className="card__top__elipse-container">
<img src={ellipsisIcon} alt="ellipsis" />
</div>
</div>
<div className="card__bottom-container">
{currentTime === 0 && (
<>
<h1 className="fs-900 text-white">{daily.current}hrs</h1>
<div className="card__bottom__prev-container">
<p className="text-accent ">
Yesterday -<span>{daily.previous}hrs</span>
</p>
</div>
</>
)}
{currentTime === 1 && (
<>
<h1 className="fs-900 text-white">{weekly.current}hrs</h1>
<div className="card__bottom__prev-container">
<p className="text-accent ">
Last Week -<span>{weekly.previous}hrs</span>
</p>
</div>
</>
)}
{currentTime === 2 && (
<>
<h1 className="fs-900 text-white">{monthly.current}hrs</h1>
<div className="card__bottom__prev-container">
<p className="text-accent">
Last Month -<span>{monthly.previous}hrs</span>
</p>
</div>
</>
)}
</div>
</div>
</div>
);
};
export default Card;
My App (Parent):
import { useState, useEffect } from 'react';
import Card from './components/Card/Card';
import {
pbImage,
ellipsisIcon,
exerciseIcon,
playIcon,
careIcon,
socialIcon,
studyIcon,
workIcon,
} from './constants/images';
const cards = [
{
name: 'Exercise',
color: 'hsl(var(--clr-exercise))',
icon: exerciseIcon,
},
{
name: 'Play',
color: 'hsl(var(--clr-play))',
icon: playIcon,
},
{
name: 'Self Care',
color: 'hsl(var(--clr-care))',
icon: careIcon,
},
{
name: 'Social',
color: 'hsl(var(--clr-social))',
icon: socialIcon,
},
{
name: 'Study',
color: 'hsl(var(--clr-study))',
icon: studyIcon,
},
{
name: 'Work',
color: 'hsl(var(--clr-work))',
icon: workIcon,
},
];
function App() {
const [selectedTime, setSelectedTime] = useState(2);
return (
<div className="app bg-dark">
<div className="main__container grid">
<div className="side__card-container">
<div className="side__card__top flex">
<div className="side__card__top__pb-container">
<img
src={pbImage}
alt="pb"
className="side__card__top__pb-image pb-image"
/>
</div>
<div className="side__card__top__person-container">
<p className="fs-600 text-accent">Report for</p>
<h2 className="fs-800 text-white">Jeremy Robson</h2>
</div>
</div>
<div className="side__card__bottom">
<div>Daily</div>
<div>Weekly</div>
<div>Monthly</div>
</div>
</div>
{cards.map((card, _index) => (
<Card
key={_index}
name={card.name}
color={card.color}
icon={card.icon}
currentTime={selectedTime}
/>
))}
</div>
</div>
);
}
export default App;
As I mentioned in the comments, states are updated asynchronously. So, you should be careful when you use a state immediately after setting its value. In your case, you shouldn’t use the data state because you are not sure that it has a value. Try changing to this.
useEffect(() => {
const fetchData = async () => {
const result = await axios.get('data.json');
const filteredData = result.data.filter((item) => {
return item.title === name;
})
setData(filteredData);
// make sure result data isn’t empty
setDaily(result.data[0].timeframes.daily);
setWeekly(result.data[0].timeframes.weekly);
setMonthly(result.data[0].timeframes.monthly);
};
fetchData();
}, []); // "[]" makes the useEffect callback only run after the first render

How do I pass props when the prop object is created?

I have a problem wherein I want to pass my props in my prop object as you see in this code
const list = [
{option:'Main',main:<Main></Main>},
{option:'Topic',
main:<Topic
uid={uid}
tindex={topicindex}
setTindex={settopicIndex}
topiclist ={topiclist}
handlePrev = {e => handlePrev(e)}
handleNext = {e => handleNext(e)}
topic={topic}
setTopic={setTopic}
handleAddComment = {e => handleAddComment(e)}
comments = { comments }
comment={comment}
setcomment={setcomment}
handleLikes = {(e) => handleLikes(e,uid,"I'll pass a item")}
handleDislikes = { (e) => handleDislikes(e,uid,"I'll pass a item")}
reacts = {reacts}
setreacts = {setreacts}
></Topic>
},
{option:'Arts',
main:<Arts
uid={uid}
postart={postart}
setpostart={e => setpostart(e)}
delart={delart}
setdelart={e => setdelart(e)}
/>
}]
This list will show in my output function but as you see my main objects will is not changeable in a loop when I try to pass my new items Examples this
handleLikes and handleDislikes, this one as you see I'll pass a item I want to pass a new item there but the item there will be constant. I'll try to explain this briefly in my full codes.
First lets start with <Topic>
const Topic = props => {
<div className="list">
{props.comments.map((item,idx) => {
return(
<div className='user'>
<div className="user-uid">
<h6> {item.uid}</h6>
</div>
<div className="user-comment">
<h5>
{item.comment}
</h5>
</div>
<div className="like-dislike">
<div className="like" onClick={(e,i) => props.handleLikes(item.uid,props.uid,item.likes)}>
{item.likes} <ion-icon name="thumbs-up-outline"></ion-icon>
</div>
<div className="dislike" onClick={(e,i) => props.handleDislikes(item.uid,props.uid,item.dislikes)} >
{item.dislikes} <ion-icon name="thumbs-down-outline"></ion-icon>
</div>
</div>
</div>
)
})}
</div>
}
This one is my call props object( I don't know what it calls to be honest.)
And this one will be my callback
const list = [
{option:'Main',main:<Main></Main>},
{option:'Topic',
main:<Topic
uid={uid}
tindex={topicindex}
setTindex={settopicIndex}
topiclist ={topiclist}
handlePrev = {e => handlePrev(e)}
handleNext = {e => handleNext(e)}
topic={topic}
setTopic={setTopic}
handleAddComment = {e => handleAddComment(e)}
comments = { comments }
comment={comment}
setcomment={setcomment}
handleLikes = {(e,i) => handleLikes(e,uid,i)}
handleDislikes = { (e,i) => handleDislikes(e,uid,i)}
reacts = {reacts}
setreacts = {setreacts}
></Topic>
},
{option:'Arts',
main:<Arts
uid={uid}
postart={postart}
setpostart={e => setpostart(e)}
delart={delart}
setdelart={e => setdelart(e)}
/>
}]
and then I will show this in my output function like this
<div className="main-body">
<div className="slideshow">
<div
className="slideshowSlider"
style={{ transform: `translate3d(${-index * 100}%, 0, 0)` }}
>
{list.map((item,idx) => {
return(
<div className='slide' key={idx}>
{item.main}
</div>
)
})}
</div>
</div>
</div>
I tried to remove the Topic props in its list and do something like this
const list = [
{option:'Main',main:<Main></Main>},
{option:'Topic',
main:<Topic
></Topic>
},
{option:'Arts',
main:<Arts
uid={uid}
postart={postart}
setpostart={e => setpostart(e)}
delart={delart}
setdelart={e => setdelart(e)}
/>
}]
And for output function
<div className="main-body">
<div className="slideshow">
<div
className="slideshowSlider"
style={{ transform: `translate3d(${-index * 100}%, 0, 0)` }}
>
{list.map((item,idx) => {
return(
<div className='slide' key={idx}>
{item.main.props ???}
// I want to pass the props here instead of doing it in
the list
</div>
)
})}
</div>
</div>
</div>
Why Am i doing this?
Here's why as you see in the handleLikes and handleDislikes there is a
<div className="like-dislike">
<div className="like" onClick={(e,i) => props.handleLikes(item.uid,props.uid,item.likes)}>
{item.likes} <ion-icon name="thumbs-up-outline"></ion-icon>
</div>
<div className="dislike" onClick={(e,i) => props.handleDislikes(item.uid,props.uid,item.dislikes)} >
{item.dislikes} <ion-icon name="thumbs-down-outline"></ion-icon>
</div>
</div>
I want to pass my item.likes and item.dislikes but the it cannot be pass on my <Topic> at list
Also this is just the code for handleLikes and handleDislikes
const handleLikes = (
main_uid,
reactor_uid,
likes
// likes_state
) => {
console.log('like')
console.log(main_uid,reactor_uid)
console.log(reacts)
console.log(likes)
}
const handleDislikes = (
main_uid,
reactor_uid,
dislikes
) => {
console.log('dislike')
console.log(main_uid,reactor_uid)
console.log(reacts)
console.log(dislikes)
}
but when I tried to console.log it the dislikes or likes just giving me the same input as the item.uid in the Topic props. So I want to do it in this way as item.main.props in part of output function.
I hope my question is clear thank you for helping me.

React Hooks throws error Hooks can only be called inside of the body of a function component.. after upgrade to web pack 4

I have Rails Application with React On Rails, recently upgraded webpack 3 to webpack 4
Rails : 4
Ruby: 2+
React: 16.9
Webpack: 4.41.5
everything works well except below code which works well with webpack 3
In the console I see below error
Uncaught Invariant Violation: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
An error occurred during a React Lifecycle function
import Error from '#material-ui/icons/Error';
import MoreHoriz from '#material-ui/icons/MoreHoriz';
import { Button, FixedFooterModal, SafeAnchor, Util } from 'lib-components';
import moment from 'moment-timezone';
import prettyBytes from 'pretty-bytes';
import React, { useState, useCallback, useMemo, useEffect } from 'react';
import Helpers from '../../../lib/lib-components/src/js/services/Helpers'; // eslint-disable-line
import styles from './ExportForm.css';
interface Export {
created_at: string;
filename: string;
filesize: number;
id: number;
project_id: number;
status: string;
updated_at: string;
options: string;
}
function parseOptions(options: string) {
return options
.split(',')
.map(option => {
switch (option) {
case 'include_done_stories':
return 'Done';
case 'include_current_backlog_stories':
return 'Current/Backlog';
case 'include_icebox_stories':
return 'Icebox';
case 'include_epics':
return 'Epics';
case 'include_attachments':
return 'Attachments';
case 'include_project_history':
return 'Project History';
}
})
.join(', ');
}
const ExportStatus: React.FunctionComponent<{
status: string;
projectId: number;
exportId: number;
csrfToken: string;
setModalOpen: (a: boolean) => void;
}> = ({ status, projectId, exportId, csrfToken, setModalOpen }) => {
const handleRetryClick = useCallback(() => {
Helpers.update(csrfToken, {
method: 'GET',
url: `/projects/${projectId}/export/${exportId}/retry`,
});
setModalOpen(true);
}, [projectId, exportId, csrfToken, setModalOpen]);
switch (status) {
case 'failed':
return (
<div data-aid='ExportForm__failed' className={styles['ExportForm__failed']}>
<div className={styles['ExportForm__failedIcon']}>
<Error fontSize='small' style={{ marginRight: '4px', color: '#CB2B1E' }} />
<span>Export failed</span>
</div>
<div data-aid='ExportForm__retryLink' className={styles['ExportForm__retryLink']}>
<SafeAnchor onClick={handleRetryClick}>retry</SafeAnchor>
</div>
</div>
);
case 'completed':
return (
<div data-aid='ExportForm__completed' className={styles['ExportForm__completed']}>
<div className={styles['ExportForm__completedIcon']}>
<CheckCircle fontSize='small' style={{ marginRight: '4px', color: '#6D902A' }} />
<span>Complete</span>
</div>
<div className={styles['ExportForm__completedDownloadLink']}>
<SafeAnchor href={`/projects/${projectId}/export/${exportId}/download`}>download</SafeAnchor>
</div>
</div>
);
default:
case 'in progress':
return (
<div className={styles['ExportForm__inProgressIcon']}>
<div className={styles['ExportForm__inProgressIconBg']}>
<MoreHoriz fontSize='small' />
</div>
<span data-aid='ExportForm__inProgress' className={styles['ExportForm__inProgress']}>
In Progress
</span>
</div>
);
}
};
const ExportForm: React.FunctionComponent<{
csrfToken: string;
id: number;
exports: Export[];
timezone: string;
}> = ({ csrfToken, id, exports, timezone }) => {
const [modalOpen, setModalOpen] = useState(false);
const [includeDoneStories, setIncludeDoneStories] = useState(true);
const [includeCurrentBacklogStories, setIncludeCurrentBacklogStories] = useState(true);
const [includeIceboxStories, setIncludeIceboxStories] = useState(true);
const [includeEpics, setIncludeEpics] = useState(true);
const [includeAttachments, setIncludeAttachments] = useState(true);
const [includeProjectHistory, setIncludeProjectHistory] = useState(true);
const setDoneStoriesFromEvent = useCallback(e => setIncludeDoneStories(e.target.checked), []);
const setCurrentBacklogStoriesFromEvent = useCallback(e => setIncludeCurrentBacklogStories(e.target.checked), []);
const setIceboxStoriesFromEvent = useCallback(e => setIncludeIceboxStories(e.target.checked), []);
const setEpicsFromEvent = useCallback(e => setIncludeEpics(e.target.checked), []);
const setAttachmentsFromEvent = useCallback(e => setIncludeAttachments(e.target.checked), []);
const setProjectHistoryFromEvent = useCallback(e => setIncludeProjectHistory(e.target.checked), []);
const handleExportClicked = useCallback(() => {
Helpers.update(
csrfToken,
{
method: 'POST',
url: `/projects/${id}/export`,
},
{
options: {
include_done_stories: includeDoneStories,
include_current_backlog_stories: includeCurrentBacklogStories,
include_icebox_stories: includeIceboxStories,
include_epics: includeEpics,
include_attachments: includeAttachments,
include_project_history: includeProjectHistory,
},
}
);
setModalOpen(true);
}, [
csrfToken,
id,
includeDoneStories,
includeCurrentBacklogStories,
includeIceboxStories,
includeEpics,
includeAttachments,
includeProjectHistory,
]);
const handleCloseModal = useCallback(() => {
setModalOpen(false);
Util.windowLocation().assign(`/projects/${id}/export`);
}, [id]);
const justRefresh = useMemo(() => exports.some(e => e.status === 'in progress'), [exports]);
useEffect(() => {
let timer: ReturnType<typeof setTimeout>;
if (justRefresh) {
timer = setTimeout(() => Util.windowLocation().reload(), 30000);
}
return () => {
clearTimeout(timer);
};
}, [justRefresh]);
return (
<div className={styles['ExportForm']}>
<h2>Create New Export</h2>
<p>
Stories, Epics, and Project History will be exported as a CSV. All files will be available to download from the
exports section below. Files are available for two weeks.
</p>
<div className={styles['ExportForm__options']}>
<div className={styles['ExportForm__option']}>
<label>
<input type='checkbox' checked={includeDoneStories} onChange={setDoneStoriesFromEvent} />
All Done Stories
</label>
</div>
<div className={styles['ExportForm__option']}>
<label>
<input
type='checkbox'
checked={includeCurrentBacklogStories}
onChange={setCurrentBacklogStoriesFromEvent}
/>
All Current/Backlog Stories
</label>
</div>
<div className={styles['ExportForm__option']}>
<label>
<input type='checkbox' checked={includeIceboxStories} onChange={setIceboxStoriesFromEvent} />
All Icebox Stories
</label>
</div>
<div className={styles['ExportForm__option']}>
<label>
<input type='checkbox' checked={includeEpics} onChange={setEpicsFromEvent} />
All Epics
</label>
</div>
<div className={styles['ExportForm__option']}>
<label>
<input
data-aid='ExportForm__attachments'
type='checkbox'
checked={includeAttachments}
onChange={setAttachmentsFromEvent}
/>
All Attachments
</label>
</div>
<div className={styles['ExportForm__option']}>
<label>
<input
data-aid='ExportForm__attachments'
type='checkbox'
checked={includeProjectHistory}
onChange={setProjectHistoryFromEvent}
/>
Project History
</label>
</div>
</div>
<Button
label={<span>Export</span>}
size='large'
type='primary'
data-aid='ExportForm__exportButton'
onClick={handleExportClicked}
/>
{modalOpen && (
<FixedFooterModal
buttons={[
{
props: {
label: 'Close',
type: 'lined',
onClick: handleCloseModal,
align: 'right',
'data-aid': 'ExportForm__closeModal',
},
},
]}
title='Export in progress'
onClose={handleCloseModal}
noScroll={true}
>
<div className={styles['ExportForm__inProgressModal']}>
<p>We're on it! We will send you an email once your data is available to download.</p>
<p>
Check back here to find all of your available exports. You can access your exported data here for two
weeks.
</p>
</div>
</FixedFooterModal>
)}
<h2>Exports</h2>
{exports.length > 0 ? (
exports.map(exp => (
<div key={exp.id} className={styles['ExportForm__export']} data-aid='ExportForm__export'>
<div className={styles['ExportForm__exportInfo']}>
<div className={styles['ExportForm__exportTimes']}>
<span data-aid='ExportForm__created'>
{moment.tz(exp.created_at, timezone).format('MMM Do, YYYY [at] h:mm A z')}
</span>
{exp.filesize ? ` (${prettyBytes(exp.filesize)}) • ` : ` • `}
<span data-aid='ExportForm__expires'>
Expires on {moment.tz(exp.created_at, timezone).add(14, 'days').format('MMM Do, YYYY')}
</span>
</div>
<div className={styles['ExportForm__exportOptions']}>
<span data-aid='ExportForm__exportOptions'>({parseOptions(exp.options)})</span>
</div>
</div>
<div className={styles['ExportForm__download']}>
<ExportStatus
status={exp.status}
projectId={exp.project_id}
exportId={exp.id}
csrfToken={csrfToken}
setModalOpen={setModalOpen}
/>
</div>
</div>
))
) : (
<div className={styles['ExportForm__emptyMessage']} data-aid='ExportForm__emptyMessage'>
<p>No exports have been created.</p>
</div>
)}
</div>
);
};
export default ExportForm;
I tried following solutions for similar error but of no help
Checked for multiple versions of react
disabling react hot loader and setConfig pureSFC to true
Used React.FunctionComponent
Also this componenet is rendered by React.lazy() later I figured all the components rendered by lazy loading have inavlid hook call

How can I render this object in React?

My JSON:
{
"id": 1,
"userId": 34,
"cerealId": 1,
"metadata": {
"latitude": "47.484574",
"longitude": "4.341844",
"precision": "461.43"
},
"createdAt": "2020-07-13T00:00:00.000Z",
"updatedAt": "2020-07-13T00:00:00.000Z"
}
I need to render the object "metadata" and this is my code:
import React,{useState,useEffect, Fragment} from 'react';
import {getCookie} from '../helpers/Helpers';
import moment from 'moment';
import { read } from './apiAdmin';
const IndividualSample = (props) => {
const token = getCookie('accessToken') //// <-- right one
//const Id = getCookie('token')
const [order, setOrder] = useState({});
const [error, setError] = useState(false);
const loadSingleOrder = orderId => {
read(orderId,token).then( data => {
if (data.error){
setError(data.error)
} else {
setOrder(data)
}
})
}
const showInput = (key, value) => {
return (
<div className="input-group mb-2 mr-sm-2">
<div className="input-group-prepend">
<div className="input-group-text">{key}</div>
</div>
<input type="text" value={value} className="form-control" readOnly/>
</div>
)
}
useEffect (() => {
const orderId = props.match.params.orderId
loadSingleOrder(orderId)
},[props])
const showSingleSample = () => {
return (
<div className="card mr-2 mt-2 mb-5">
<ul className="list-group">
<li className='list-group-item'>ID Sample: {order.id} </li>
<li className="list-group-item">User ID: {order.userId}</li>
<li className="list-group-item">Cereal ID: {order.cerealId}</li>
<li className='list-group-item' style={{fontWeight:'bold'}}>Created At:{" "}
{moment(order.createdAt).locale('es').format('LL')}
</li>
<h2 className='mt-2 mb-5 text-center' >METADATA :</h2>
{order.data?.map((p, pIndex) => (
<div className='mb-4' key={pIndex} style={{padding:'20px', border:'1px solid indigo'}}>
I need render this ---> {showInput('Latitude:', p.latitude)}
{showInput('Longitude:', p.longitude)}
</div> ))}
</ul>
</div>
)
}
return(
<>
<h1>Soy Individual samples</h1>
<div className='container'>
{showSingleSample()}
{JSON.stringify(order.metadata)}
</div>
</>
)
}
I can render the other params cerealId, userId etc. But as I didn't receive the object as an array I don't know how render it in the right way.
I can only see the params in JSON.stringify(order.metadata),but I need to render them inside a div tag.
I can't render the 'metadata'. If someone can help me I will appreciate it!
metadata is an object, you will have to use Object.entries (polyfill may be needed):
{ Object.entries(order.metadata).map(([key, value]) => (
<div>{key}: {value}</div>
))}
Also, make sure it's order.metadata or order.data.

Categories