How to load data onto a React State from an API instead of local json file? - json

So as part of my project I'm trying to ammend this boilerplate of React-Pdf-Highlighter to accept pdf highlights from flask-api instead of a local file( the example came with a local/json import) ..
I have tried to check with console.log the fetch is not the problem, but I feel for somereason the 'testHighlights' state is not what it should be .
<<App.js>>
// #flow
/* eslint import/no-webpack-loader-syntax: 0 */
import React, { Component } from "react";
import PDFWorker from "worker-loader!pdfjs-dist/lib/pdf.worker";
import {
PdfLoader,
PdfHighlighter,
Tip,
Highlight,
Popup,
AreaHighlight,
setPdfWorker
} from "react-pdf-highlighter";
import Spinner from "./Spinner";
import Sidebar from "./Sidebar";
import testHighlights from "./test-highlights";
import type {
T_Highlight,
T_NewHighlight
} from "react-pdf-highlighter/src/types";
import "./style/App.css";
setPdfWorker(PDFWorker);
type Props = {};
type State = {
url: string,
highlights: Array<T_Highlight>
};
const getNextId = () => String(Math.random()).slice(2);
const parseIdFromHash = () =>
document.location.hash.slice("#highlight-".length);
const resetHash = () => {
document.location.hash = "";
};
const HighlightPopup = ({ comment }) =>
comment.text ? (
<div className="Highlight__popup">
{comment.emoji} {comment.text}
</div>
) : null;
const PRIMARY_PDF_URL = "https://arxiv.org/pdf/1708.08021.pdf";
const SECONDARY_PDF_URL = "https://arxiv.org/pdf/1604.02480.pdf";
const searchParams = new URLSearchParams(document.location.search);
const initialUrl = searchParams.get("url") || PRIMARY_PDF_URL;
class App extends Component<Props, State> {
state = {
url: initialUrl,
highlights: testHighlights[initialUrl]
? [...testHighlights[initialUrl]]
: []
};
state: State;
resetHighlights = () => {
this.setState({
highlights: []
});
};
toggleDocument = () => {
const newUrl =
this.state.url === PRIMARY_PDF_URL ? SECONDARY_PDF_URL : PRIMARY_PDF_URL;
this.setState({
url: newUrl,
highlights: testHighlights[newUrl] ? [...testHighlights[newUrl]] : []
});
};
scrollViewerTo = (highlight: any) => {};
scrollToHighlightFromHash = () => {
const highlight = this.getHighlightById(parseIdFromHash());
if (highlight) {
this.scrollViewerTo(highlight);
}
};
componentDidMount() {
window.addEventListener(
"hashchange",
this.scrollToHighlightFromHash,
false
);
}
getHighlightById(id: string) {
const { highlights } = this.state;
return highlights.find(highlight => highlight.id === id);
}
addHighlight(highlight: T_NewHighlight) {
const { highlights } = this.state;
console.log("Saving highlight", highlight);
this.setState({
highlights: [{ ...highlight, id: getNextId() }, ...highlights]
});
}
updateHighlight(highlightId: string, position: Object, content: Object) {
console.log("Updating highlight", highlightId, position, content);
this.setState({
highlights: this.state.highlights.map(h => {
const {
id,
position: originalPosition,
content: originalContent,
...rest
} = h;
return id === highlightId
? {
id,
position: { ...originalPosition, ...position },
content: { ...originalContent, ...content },
...rest
}
: h;
})
});
}
render() {
const { url, highlights } = this.state;
return (
<div className="App" style={{ display: "flex", height: "100vh" }}>
<Sidebar
highlights={highlights}
resetHighlights={this.resetHighlights}
toggleDocument={this.toggleDocument}
/>
<div
style={{
height: "100vh",
width: "75vw",
position: "relative"
}}
>
<PdfLoader url={url} beforeLoad={<Spinner />}>
{pdfDocument => (
<PdfHighlighter
pdfDocument={pdfDocument}
enableAreaSelection={event => event.altKey}
onScrollChange={resetHash}
// pdfScaleValue="page-width"
scrollRef={scrollTo => {
this.scrollViewerTo = scrollTo;
this.scrollToHighlightFromHash();
}}
onSelectionFinished={(
position,
content,
hideTipAndSelection,
transformSelection
) => (
<Tip
onOpen={transformSelection}
onConfirm={comment => {
this.addHighlight({ content, position, comment });
hideTipAndSelection();
}}
/>
)}
highlightTransform={(
highlight,
index,
setTip,
hideTip,
viewportToScaled,
screenshot,
isScrolledTo
) => {
const isTextHighlight = !Boolean(
highlight.content && highlight.content.image
);
const component = isTextHighlight ? (
<Highlight
isScrolledTo={isScrolledTo}
position={highlight.position}
comment={highlight.comment}
/>
) : (
<AreaHighlight
highlight={highlight}
onChange={boundingRect => {
this.updateHighlight(
highlight.id,
{ boundingRect: viewportToScaled(boundingRect) },
{ image: screenshot(boundingRect) }
);
}}
/>
);
return (
<Popup
popupContent={<HighlightPopup {...highlight} />}
onMouseOver={popupContent =>
setTip(highlight, highlight => popupContent)
}
onMouseOut={hideTip}
key={index}
children={component}
/>
);
}}
highlights={highlights}
/>
)}
</PdfLoader>
</div>
</div>
);
}
}
export default App;
<<test-highlights.js >>
const testHighlights =async () => {
const res= await fetch('http://127.0.0.1:5000/jsonapi')
const data =await res.json()
console.log(data)
this.state.testHighlights = data
return testHighlights;
}
export default testHighlights;

You can't assign state like this
this.state.testHighlights = data
You must use this.setState function to do it
this.setState({ testHighlights: data });
That is why your testHighlights state isn't what you was expected

Related

React Native Download JSON but not displaying in Flatlist

I am trying to download the JSON. React Native is downloading the json but I am not sure why Flatlist is not displaying the items. If I change the data={dummyData} in flatlist to data={MyList} then, the flatlist is able to display.
let viewableItemsChanged = null;
const dummyData = GrabData('http://hunterdata.serveblog.net/10record.json');
const MyList = [
{"id":"0","title":"MyBook0","url":"URLBook-0","image":"image-0" },
{"id":"1","title":"MyBook1","url":"URLBook-1","image":"image-1" },
{"id":"2","title":"MyBook2","url":"URLBook-2","image":"image-2" },
{"id":"3","title":"MyBook3","url":"URLBook-3","image":"image-3" },
{"id":"4","title":"MyBook4","url":"URLBook-4","image":"image-4" },
{"id":"5","title":"MyBook5","url":"URLBook-5","image":"image-5" }];
async function GrabData(TheURL) {
let abc = [];
try {
let response = await fetch(TheURL, {headers: {'Cache-Control' : 'no-cache'}});
let responseJson = await response.json();
console.log(responseJson);
return responseJson;
} catch (error) {
console.error(error);
}
}
const renderItem = ({item}) => {
return <View><Text>{item.title}</Text></View>
}
const List = () => {
return (
<FlatList
style={styles.list}
data={dummyData}
renderItem={renderItem}
/>
)
};
there is an issue with your code. you are calling the async function without await keyword. so it returns undefine response like this. {"_U": 0, "_V": 0, "_W": null, "_X": null}
Please Try this solution.
import React, { useEffect , useState } from 'react';
import { SafeAreaView, View, FlatList, StyleSheet, Text, StatusBar } from 'react-native';
const Item = ({ title }) => (
<View style={styles.item}>
<Text style={styles.title}>{title}</Text>
</View>
);
const App = () => {
const [data, setData] = useState([])
useEffect(() => {
apicall();
},[])
const apicall = async () => {
let dd = await GrabData("http://hunterdata.serveblog.net/10record.json");
setData(dd)
}
const GrabData = async (TheURL) => {
try {
let response = await fetch(TheURL, {headers: {'Cache-Control' : 'no-cache'}});
let responseJson = await response.json();
return responseJson;
} catch (error) {
console.error(error);
}
}
const renderItem = ({ item }) => (
<Item title={item?.title} />
);
return (
<SafeAreaView style={styles.container}>
<FlatList
data={data}
renderItem={renderItem}
keyExtractor={item => item?.id}
/>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
marginTop: StatusBar.currentHeight || 0,
},
item: {
backgroundColor: '#f9c2ff',
padding: 20,
marginVertical: 8,
marginHorizontal: 16,
},
title: {
fontSize: 32,
},
});
export default App;
You should activate the functions in componentDidMount also try states instead of const

How can i React ( get axios from Json and ReRandering my page)

Why am I asking this question (main return) is finsied, but board.writer is not drawing. how can i drawing this object
if my question is wrong way plz tell me . i will fix it
i tried this way
first use map function
make like this function renderUser = ({board_SEQ, content, writer,subject}) => { parameter}
const Home = () => {
const initboard = {
board_SEQ: '',
writer: '',
content: '',
subject: ''
};
const [boards, setBoard] = useState([]);
const load = () => {
axios.get('http://www.heon.shop:8080/api/boards')
.then((res) => {
const data = res.data;
setBoard(boards => [...boards, {
board_SEQ: (data[0].board_SEQ),
writer: data[0].writer,
content: data[0].content,
subject: data[0].subject
}]);
})
.catch((error) => {
console.log("error" + error);
}
);
}
useEffect(() => {
load();
console.log("useEffect");
}, []);
const renderUser = ({board_SEQ, content, writer, subject}) => {
return (
<div>
<li>he</li>
<li>{board_SEQ}</li>
<li>{content}</li>
<li>{writer}</li>
<li>{subject}</li>
</div>
);
}
return (
<div>
{boards.map(board => {
<h1> {board.writer}</h1>
})}
</div>
);
}
export default Home;
Maybe you can try like this,
<div>
{boards.map(board => renderUser(board)}
</div>
if you want to render item directly using (add return to the map):
<div>
{boards.map(board => {
return <h1> {board.writer}</h1>;
})}
</div>

How to get All JSON object from local JSON file in React functional component?

I'm using functional component and I'm getting JSOS object from local file And in component I'm setting that JSON in some state.
After that few object I spliced(deleted) from that setState. But again in onchange function I want all the JSON object but here I'm getting updated json means few are deleted, Is there any method I can store all JSON object in some place? can anybody help me in this.
const StudyDetails = () => {
const [supplyPlan, setSupplyPlan] = useState([]);
const getSupplyPlanDetails = useCallback(
async () => {
try {
const payload = {
studyName: studyDetails?.studyName
? studyDetails?.studyName
: query.get("name"),
country: [],
depot: [],
material: [],
site: [],
inTransientMaterial,
};
const res = await getSupplyPlan(payload);
//setSupplyPlan(res);
console.log(res)
// setSupplyPlan(supplyData)
} catch (err) {
setSupplyPlan([]);
}
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[]
);
useEffect(() => {
getSupplyPlanDetails();
}, [ getSupplyPlanDetails]);
const onChange = (e) => {debugger
console.log(supplyData)
}
return (
<div>
<Checkbox
onChange={onChange}
>
In Transit
</Checkbox>
{supplyPlan?.map((item, index) => (
<Fragment key={index}>
<SupplyChain item={item} />
<Divider className="supply-chain-divider" />
</Fragment>
))}
</div>
)
}
I'm splicing few object in supplyChain component:
const SupplyChain = ({ item }) => {
useEffect(() => {
let data = [];
if (item && item.inTransit.length != 1) {
item &&
item.inTransit &&
item.inTransit.length > 0 &&
item.inTransit.map((intrans, index) => {
if (
intrans.from === item.depots?.packagingDepot?.[0]?.depotName &&
intrans.to === "sites"
) {
let directPath = item.inTransit.splice(index, 1);
setDirectSite(directPath);
}
setFilterJson(item.inTransit);
// eslint-disable-next-line react-hooks/exhaustive-deps
item = { ...item, filterJson: item.inTransit };
});
}
}
So if again when I click on onchange function I want all objects of JSON.
please someone help me in this

Can't access JSON data and print Begin and End only React Native

I'm trying to access to Begin and End inside JSON data but I can't. It just accesses and prints JSON data.
How can I print the Begin and End in separately FlatList?
Here is my code :
manage = date => {
this.setState({status: true})
this.setState({date:date})
const office_id=this.state.office_id;
const duration=this.state.duration;
const url='http://MyIP/api/timeApi';
axios.post(url,{office_id,date,duration})
.then(resp => this.setState({
testArray : JSON.stringify(resp.data),
}))
.catch(e)
{
alert(e);
}}
testFunction = () => {
var x = this.state.testArray;
return(
<Text>{x}</Text>
)
}
<DatePicker
date={this.state.date}
onDateChange={this.manage.bind(this) } />
in return
{
this.state.status ? <View>
<FlatList
data={this.state.testArray}
renderItem={this.testFunction}
/>
</View> : null
}
and here is my result
you need something like this , try to change it based on your code
import React, { Component } from 'react';
import {Text, View, FlatList ,Button} from 'react-native';
export default class Test extends Component {
constructor() {
super();
this.state = {
data: ['one', 'two', 'three', 'four', 'five'],
}
}
_keyExtractor = (item, index) => index.toString();
_renderItem = ({ item }) => (
<View>
<Text>{item}</Text>
</View>
);
manage = () => {
var x = this.firstAndLast(this.state.data);
this.setState({
data : x
})
}
firstAndLast(myArray) {
var firstItem = myArray[0];
var lastItem = myArray[myArray.length-1];
var newArray = [];
newArray.push(firstItem);
newArray.push(lastItem);
return newArray;
}
render() {
return (
<View>
<FlatList
data={this.state.data}
extraData={this.state}
keyExtractor={this._keyExtractor}
renderItem={this._renderItem}
/>
<Button title="click" onPress={() => this.manage()} />
</View>
);
}
}

Why my this.state is null?

I'm new with React and i'm trying to render a json from a websocket.
Right now i'm able to get the json from the websocket using this :
componentWillMount() {
this.ws = new WebSocket('ws://10.77.0.79:1234')
this.ws.onmessage = e => this.setState({data: Object.values((e.data))})
this.ws.onerror = e => this.setState({ error: 'WebSocket error' })
this.ws.onclose = e => !e.wasClean && this.setState({ error: `WebSocket error: ${e.code} ${e.reason}` })
}
And then i need to map this json, right now i'm using this:
render() {
// this is my json from websocket
var json2 = {"Auth":{"status":"true","user":"gesplan","pass":"root"}}
var arr = [];
Object.keys(json2).forEach(function(key) {
arr.push(json2[key]);
});
return <ul>{arr.map(item => <MyAppChild key={item.status} label={item.status} value={item.user} pass={item.pass} />)} {this.state.data} </ul>;
}
}
class MyAppChild extends React.Component {
render() {
return <li>{this.props.label + " - " + this.props.value + this.props.pass } </li>;
}
}
With this i can render the values of the var json2.
How can i do it with my this.state.data? when i change json2 for this.state.data it return a null, but how can the state be null if i am rendering it normally?
Set your initial state to an empty array first. Append data when new data comes in:
constructor() {
this.state = {
data: []
}
}
componentWillMount() {
this.ws = new WebSocket('ws://10.77.0.79:1234')
this.ws.onmessage = e => this.setState({
data: [].concat(this.state.data, JSON.parse(e.data).Auth)
})
this.ws.onerror = e => this.setState({ error: 'WebSocket error' })
this.ws.onclose = e => !e.wasClean && this.setState({ error: `WebSocket error: ${e.code} ${e.reason}` })
}
render() {
return (
<ul>
{this.state.data.map(item =>
<MyAppChild key={item.status} label={item.status} value={item.user} pass={item.pass} />)
}
</ul>
);
}