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

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

Related

Change number of servings on click (React Hooks - API)

I'm working on a recipe site using API from a third party and want to change the number of servings (which is output from the API data) when clicking the + & - button. I tried assigning the output serving amount <Servings>{recipe.servings}</Servings> in a variable and useState to update it but it kept showing errors. I would appreciate any help (preferably using react Hooks). Thanks :)
Here is my code:
const id = 716429;
const apiURL = `https://api.spoonacular.com/recipes/${id}/information`;
const apiKey = "34ac49879bd04719b7a984caaa4006b4";
const imgURL = `https://spoonacular.com/cdn/ingredients_100x100/`;
const {
data: recipe,
error,
isLoading,
} = useFetch(apiURL + "?apiKey=" + apiKey);
const [isChecked, setIsChecked] = useState(true);
const handleChange = () => {
setIsChecked(!isChecked);
};
return (
<Section>
<h2>Ingredients</h2>
<ServingsandUnits>
{recipe && (
<ServingsIncrementer>
<p>Servings: </p>
<Minus />
<Servings>{recipe.servings}</Servings>
<Plus />
</ServingsIncrementer>
)}
<ButtonGroup>
<input
type="checkbox"
id="metric"
name="unit"
checked={isChecked}
onChange={handleChange}
/>
<label htmlFor="male">Metric</label>
</ButtonGroup>
</ServingsandUnits>
</Section>
};
My custom hook is called useFetch:
const useFetch = (url) => {
const [data, setData] = useState(null);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const abortCont = new AbortController();
fetch(url, { signal: abortCont.signal })
.then((res) => {
if (!res.ok) {
// error coming back from server
throw Error("Could not fetch the data for that resource");
}
return res.json();
})
.then((data) => {
setIsLoading(false);
setData(data);
setError(null);
})
.catch((err) => {
if (err.name === "AbortError") {
console.log("Fetch aborted");
} else {
// auto catches network / connection error
setIsLoading(false);
setError(err.message);
}
});
return () => {
abortCont.abort();
};
}, [url]);
return { data, isLoading, error };
};
export default useFetch;

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

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

JSON.parse issue with redux state

Using React and Redux, I'm making the call getNoteById which returns some string inside of note.
I want to JSON.parse the note variable but if it's undefined then setValue to initialValue where I know it will parse properly.
The issue I'm having is when I check to see if JSON.parse(note) is undefined or not, I always get the same error of undefined index at 0.
Not sure how to fix this. When the component loads and getNotesById() is called, notes or initialValue should be displayed when i call setValue.
const TextEditor = ({ note, getNoteById, clearValues }) => {
const paramId = match.params.notes;
const [value, setValue] = useState();
useEffect(() => {
getNoteById(paramId);
if (JSON.parse(note) == undefined) {
setValue(initialValue);
} else {
setValue(JSON.parse(note));
}
return () => {
clearValues();
};
}, [paramId, value]);
return (
<div>
<h1> {value} </h1>
</div>
);
};
Your effect has missing dependencies: clearValues, getNoteById and note. You should skip the setValue to initialValue and do const [value, setValue] = useState(initialValue); because an effect runs after the render and note will be undefined on first render. Check if note is undefined with if(note!==undefined){setValue(JSON.parse(note))}.
Your code should look something like this:
const TextEditor = ({ note, getNoteById, clearValues }) => {
const paramId = match.params.notes;
const [value, setValue] = useState(initialValue);
useEffect(() => {
getNoteById(paramId);
if(note!==undefined) {
setValue(JSON.parse(note));
}
return () => {
clearValues();
};
}, [clearValues, getNoteById, note, paramId, value]);
return (
<div>
<h1> {value} </h1>
</div>
);
};
My guess is that you don't want to dispatch getNoteById again when the note is loaded and set in the redux state. Maybe create 2 effects:
const TextEditor = ({ note, getNoteById, clearValues }) => {
const paramId = match.params.notes;
const [value, setValue] = useState(initialValue);
//dispatch getNoteById when param id changes
useEffect(() => {
getNoteById(paramId);
return () => {
//dispatch a cleanup action
clearValues();
};
}, [clearValues, getNoteById, paramId]);
//set the note to it's parsed json when it changes
// and is not undefined
useEffect(() => {
if (note !== undefined) {
setValue(JSON.parse(note));
}
}, [note]);
return (
<div>
<h1> {value} </h1>
</div>
);
};

How to Fetch Json with React-Table library

the example to which I refer is the following:
https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/sub-components
I would like to fetch a json file and pass the elements of the latter into the table instead of generating them as in the previous example.
The instructions for making fetch are clear to me but I can't understand how to integrate them in the "makeData" file.
This is my "makeData" code:
import ReactDOM from 'react-dom';
const range = len => {
const arr = []
for (let i = 0; i < len; i++) {
arr.push(i)
}
return arr
}
const newPerson = () => {
fetch('http://localhost:5000/api/azienda')
.then(res => res.json())
// .then((rows) => {
// ReactDOM.render(this.makeData(rows), document.getElementById('root'));
// });
}
export default function makeData(...lens) {
const makeDataLevel = (depth = 0) => {
const len = lens[depth]
return range(len).map(d => {
return {
...newPerson(),
subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined,
}
})
}
return makeDataLevel()
}
For any advice I will thank you
Create an array in the constructor ,where the data will be stored , fetch the data from the serverlink and then put it in the table
constructor(props, context) {
super(props, context);
this.state = { items: []};
}
getList = () => {
fetch("http://localhost:5000/api/azienda")
.then(res => res.json())
.then(items => this.setState({ items }))
.catch(err => console.log(err));
};
componentDidMount() {
this.getList();
}

How to get the length of the response from a fetch request?

I have got series of data that contains some objects in one array(json file) and it will be shown by react.
Here is my code:
class App extends React.Component {
constructor(props){
super(props);
this.state = {
data: [],
library:null,
perPage: 20,
currentPage: 1,
maxPage: null,
filter: ""
};
}
componentDidMount() {
fetch('/json.bc')
// Here I want to get the length of my respose
.then(response => response.text())
.then(text => {
var Maindata = JSON.parse(text.replace(/\'/g, '"'))
this.setState(state => ({
...state,
data: Maindata
}), () => {
this.reorganiseLibrary()
})
}).catch(error => console.error(error))
}
reorganiseLibrary = () => {
const { filter, perPage , data } = this.state;
let library = data;
if (filter !== "") {
library = library.filter(item =>
item.hotelinfo.hotelsearch.realname.toLowerCase().includes(filter)
);
}
library = _.chunk(library, perPage);
this.setState({
library,
currentPage: 1,
maxPage: library.length === 0 ? 1 : library.length
});
};
// Previous Page
previousPage = () =>
this.setState(prevState => ({
currentPage: prevState.currentPage - 1
}));
// Next Page
nextPage = () =>
this.setState(prevState => ({
currentPage: prevState.currentPage + 1
}));
// handle filter
handleFilter = evt =>
this.setState(
{
filter: evt.target.value.toLowerCase()
},
() => {
this.reorganiseLibrary();
}
);
// handle per page
handlePerPage = (evt) =>
this.setState({
perPage: evt.target.value
}, () => this.reorganiseLibrary());
// handle render of library
renderLibrary = () => {
const { library, currentPage } = this.state;
if (!library || (library && library.length === 0)) {
return <div class="tltnodata">no result!</div>;
}
return library[currentPage - 1].map((item, i) => (
<input type="hidden" value={item.hotelinfo.hotelsearch.hotelid} name="hotelid"/>
));
};
render() {
const { library, currentPage, perPage, maxPage } = this.state;
return (
<div className="Main-wrapper">
<div class="filter_hotelname"><input value={this.state.filter} onChange={this.handleFilter} class="hotelName" /></div>
<div class="countHotel"> <span class="numbersearch"></span> // Here I want two show the count of items </div>
<div className="wrapper-data">
{this.renderLibrary()}
</div>
<div id="page-numbers">
<div class="nexprev">
{currentPage !== 1 && (
<button onClick={this.previousPage}><span class="fa-backward"></span></button>
)}
</div>
<div className="data_page-info">
{this.state.currentPage} از {this.state.maxPage}
</div>
<div class="nexprev">
{(currentPage < maxPage) && (
<button onClick={this.nextPage}><span class="fa-forward"></span></button>
)}
</div>
</div>
</div>
);
}
}
ReactDOM.render(<App/>, document.getElementById('Result'));
I want to find the length of response from a request with fetch. Also I want to know how to find the count of items that will be shown by renderLibrary . For example in json.bc we have 4 objects I want to show 4 in numbersearch span.
Using Fetch API you can find json response item length by running below code snippet. I have also added comment in code as well.
fetch('https://jsonplaceholder.typicode.com/todos')
.then(response => {
//below method return promise based response by converting stream object to json
return response.json();
}).then(json => {
//Once succcessful callback return you can find length of number of item
console.log(json);
alert("Number of item:"+json.length)
})
fetch('https://jsonplaceholder.typicode.com/todos')
.then(response => {
//below method return promise based response by converting stream object to json
return response.json();
}).then(json => {
//Once succcessful callback return you can find length of number of item
alert(json.length)
})
You can use the length of the data array from the state to distinguish the number of items.
Since arrays start at 0, you will need to increment the count by one. Here's an example snippet below that you can use in your code sample.
<div class="countHotel"><span class="numbersearch">{this.state.data && this.state.data.length + 1}</span></div>