How to fetch data from a specific user - json

So my question is, how do i link every Item to the right users and how to fetch the data right?
I want ever user in my json db to have a multiple goalItems. As every User has a unique Id, for fetching the data only from the specific user i tried by using "fetch ('http://localhost:5000/goalItems? usersId={usersId}')" but it didn't work.
Down Below you can find the DB.json file, the FULLGOAl Component, thats where the data is fetched and the GoalItem-Component
DB.JSON
{
"users": [
{
"id": "1",
"name": "Jules",
"logindate": ""
}
],
"goalItems": [
{
"id": 1,
"usersId": "",
"text": "XY",
"completed": false,
"completedDate": "18.2.2022, 14:18:24",
"note": "XY"
},
{
"id": 2,
"usersId": "",
"text": "ZY",
"completed": true,
"completedDate": "17.2.2022, 16:40:56",
"note": "ZY"
}
]
}
FullGoal this is where the data is fetched
import React, {useState, useEffect} from 'react'
import GoalItems from './GoalItems'
import DropDownMenu from "./DropDownMenu"
import CompletedLevelPopUp from './CompletedLevelPopUp'
import {useParams} from "react-router-dom";
import levelBatch1 from "./Icons/LevelBatch1.svg"
import levelBatch2 from "./Icons/LevelBatch2.svg"
const levelOption ={
1:
["A",
"B",
"C"
],
2: ["D",
"E",
"F"
}
const FullGoal = ({setNextLevelOpen}) => {
const [editLevel, setEditLevel] = useState(true)
const [goalItems, setGoalItems] = useState ([])
const [completedDate, setCompletedDate] = useState (false)
useEffect (() => {
var completedItems = []
goalItems.forEach(g => g.completed === true | completedItems.push(g.completed))
console.log(completedItems)
if(completedItems.length > 0){
function allCompl(element) {
return element === true
}
completedItems.every(allCompl) ? setOpenPopup (true) : setOpenPopup(false)
}
}, [goalItems])
useEffect (() => {
const getGoalItems = async () => {
const goalItemsFromServer = await fetchGoalItems()
setGoalItems(goalItemsFromServer)
}
getGoalItems()
}, [])
// Fetch Goals
const fetchGoalItems = async () => {
const res = await fetch ('http://localhost:5000/goalItems? usersId={usersId}')
const data = await res.json()
return data
}
//Fetch Goal
const fetchGoal = async (id) => {
const res = await fetch (`http://localhost:5000/goalItems/${id}`)
const data = await res.json()
return data
}
const addGoal = async (goal, id) =>{
const res = await fetch (`http://localhost:5000/goalItems`, {
method:'POST',
headers:{
'Content-type': 'application/json'
},
body: JSON.stringify(goal)
})
const data= await res.json ()
setGoalItems([...goalItems, data])
}
const toggleChecked = async (id) =>{
const goalToToggle = await fetchGoal(id)
const updatedGoal = {...(goalToToggle), completed : !goalToToggle.completed , completedDate : new Date().toLocaleString() + ""}
const res = await fetch (`http://localhost:5000/goalItems/${id}`, {
method: 'PUT',
headers: {
'Content-type': 'application/json',
},
body: JSON.stringify(updatedGoal)
})
const data = await res.json()
setGoalItems(goalItems.map((goal)=> goal.id === id
? {...(goal), completed: data.completed, completedDate:data.completedDate} : goal
))}
const deleteFromJson = async (id) => {
await fetch(`http://localhost:5000/goalItems/${id}`, {
method: 'DELETE'
})
setGoalItems(goalItems.filter((goal) => goal.id !== id))
}
const noteSaveJson = async (id) => {
goalItems.forEach( async e=> {
const res = await fetch (`http://localhost:5000/goalItems/${e.id}`, {
method: 'PUT',
headers: {
'Content-type': 'application/json',
},
body: JSON.stringify(e)
})
})
}
useEffect (noteSaveJson, [goalItems])
return (
<div className="fullGoal">
<div className="dropDownMenuBox">
{editLevel && <DropDownMenu options={levelOption[level] || [] } onAdd={addGoal}/> }
</div>
<div className="goalItemsBox">
<GoalItems id="goalItemBox"
goalItems={goalItems}
completedDate={completedDate}
onChange={v => {
setGoalItems(v)
}}
onToggle={toggleChecked}
editLevel={editLevel}
onDelete={deleteFromJson} />
</div>
</div>
)
}
export default FullGoal
** THIS IS THE GOALITEM COMPONENT **
import React, {useState} from 'react'
import {TiDelete} from 'react-icons/ti'
import {AiFillCheckCircle} from 'react-icons/ai'
import {CgNotes} from 'react-icons/cg'
const GoalItems = ({goalItems, onToggle, editLevel, onChange, onDelete, completedDate}) => {
const [noteOpen, setNoteOpen] = useState (false)
return (
<>
{goalItems.map((goal, index)=>(
<>
<div key={goal.id} className= {`singleGoalItem ${goal.completed ? 'completed' : ''}`} onDoubleClick={()=>onToggle(goal.id)}>
<h3 id="goalTitle">{goal.text}</h3>
<CgNotes id="goalIconNote" onClick={()=> setNoteOpen(!noteOpen)}/>
{editLevel && <TiDelete id="goalIconDelete" onClick={()=> {
onDelete(goal.id)
goalItems.splice(index, 1)
onChange([...goalItems])
}}/>}
{goal.completed ? <AiFillCheckCircle id="goalIconCheck"/> : ''}
</div>
<div>
{noteOpen? <div className="noteBox">
<textarea title="Note"
type ="text"
value= {goal.note}
onChange= {(e)=> {
goalItems[index].note= e.target.value
onChange([...goalItems])}}
placeholder='Füge hier Notizen, Ideen, Pläne ein'
/> </div> : ""}
</div>
</>
))
}
</>
)
}
export default GoalItems

Related

Why am i only seeing "id" in my react app when the fetch get all the data from Strapi?

i am trying Strapi for the first time, and i cant put my raw data into my divs.
On Strapi everything is published, and for the public the get and getOne is checked.
This way i can only see the "id" nothing else.
Any guess?
here is my result from fetch:
Here is the code that i got from the tutorial page:
import { useEffect, useState } from 'react';
import "./App.css"
// Parses the JSON returned by a network request
const parseJSON = (resp) => (resp.json ? resp.json() : resp);
// Checks if a network request came back fine, and throws an error if not
const checkStatus = (resp) => {
if (resp.status >= 200 && resp.status < 300) {
return resp;
}
return parseJSON(resp).then(resp => {
throw resp;
});
};
const App = () => {
const [error, setError] = useState(null);
const [restaurants, setRestaurants] = useState([]);
useEffect(() => {
fetch('http://localhost:1337/api/restaurants', { headers:{ 'Content-Type': 'application/json' },
method: 'GET' })
.then(checkStatus)
.then(parseJSON)
.then(({ data }) => setRestaurants(data))
.catch((error) => setError(error))
}, [])
if (error) {
// Print errors if any
return <div>An error occured: {error.message}</div>;
}
return (
<div>
<div>
{restaurants.map(({ id, name, description }) => (
<div className="black" key={id}>
{name}
{description}
{id}
</div>
))}
</div>
</div>
);
};
export default App;
I figured it out forom Google.
The map section needs to be changed to this:
{restaurants && restaurants.map((restaurant) => (
<div className="black" key={restaurant.id}>
{restaurant.attributes.name}
{restaurant.attributes.description}
{restaurant.id}
{restaurant.attributes.publishedAt}
</div>
))}

Trying to retrive JSON Array through fetch in react native but JSON parse error:Unreconised token "<"

In the code,i am fetching the token from expo-secure-store,later fetching the API data from fetchdata function.But unfortunately error "unrecognized token" is displayed.
After the error is displayed,the API call returns JSON Array data.Unable to do data map in react native to TradeCard Component.
import { StatusBar } from 'expo-status-bar';
import {React,useState,useEffect} from 'react';
import TradeCard from './TradeCard';
import { StyleSheet, Text, View,TextInput,TouchableOpacity,ScrollView,ActivityIndicator } from 'react-native';
import * as SecureStore from 'expo-secure-store';
export default function Trades()
{
const [ data,setData] = useState([]);
const [ isLoading,setLoading] = useState(true);
const [user,setUser] = useState('');
const [token,setToken] = useState('');
const fetchTokens = async () => {
try {
const user = await SecureStore.getItemAsync('user');
const token = await SecureStore.getItemAsync('token');
setUser(user);
setToken(token);
if (user && token)
{
fetchData();
}
else
{
}
} catch (e) {
alert('Error',e);
}
}
useEffect(()=>{ fetchTokens()},[]);
const fetchData = async () => {
setLoading(true);
fetch('https://tradecoaster.herokuapp.com/api/v1/listTrades/'+user+'/',
{
method:'GET',
headers:{
'Accept':'application/json',
'Content-Type':'application/json',
'Authorization':'token '+token
}
})
.then(res => res.json())
.then((res)=>{
console.log('Data',res);
setData(res);
setLoading(false);
})
.catch((error)=>{
setLoading(false);
alert(error);
console.error("Error",error);
});
}
return(
<ScrollView>
<View>
{isLoading && data.length==0 ? <ActivityIndicator size="large" color="#0000ff" /> :
<Text>No Trades</Text>
}
</View>
</ScrollView>
);
}```

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

Trying to fetch a specific record in JSON file

I am trying to fetch just one record from my JSON file, the JSON file is in the public folder
I set up a codesandbox https://codesandbox.io/live/7gu09fv
What is happening now is that it just returns the first record from the JSON and isn't matching the id to pageId
import React, { useState, useEffect } from 'react';
import {
useLocation
} from "react-router-dom";
function FetchContent( { pageId } ) {
const [page, setPage] = useState([]);
useEffect(() => {
fetch("pages.json" ,{
headers : {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
})
.then(res => res.json())
.then(json =>{
setPage(json)
}
)
}, []);
const found = page.find(id => id = { pageId });
if (!found) return <div />;
return (
<>
<h1 key={found.id}>{found.title.rendered}: {found.id} : {pageId}</h1>
</>
);
}
function Page() {
const { state: { pageId } } = useLocation();
return (
<div className="container-fluid">
<FetchContent pageId={pageId} />
</div>
);
}
export default Page;
import React, { useState, useEffect } from "react";
import { useLocation } from "react-router-dom";
function FetchContent({ pageId }) {
const [foundItem, setFoundItem] = useState();
useEffect(() => {
fetch("pages.json", {
headers: {
"Content-Type": "application/json",
Accept: "application/json"
}
})
.then((res) => res.json())
.then((json) => {
const found = json.find(({id}) => (id === pageId));
setFoundItem(found);
});
}, [pageId]);
if (!foundItem) return <div />;
return (
<>
<h1 key={foundItem.id}>
{foundItem.title && foundItem.title.rendered ? foundItem.title.rendered: ''}: {foundItem.id} : {pageId}
</h1>
</>
);
}
function Page() {
const location = useLocation();
const [pageId, setPageId] = useState(null);
useEffect(()=> {
if(location.state){
setPageId(parseInt(location.state.pageId, 10));
}
}, [location]);
return (
<div className="container-fluid">
<FetchContent pageId={pageId} />
</div>
);
}
export default Page;
Try this:
const found = page.find(obj => obj.id === pageId);

How can I make a search box in react-hooks?

I'm making a cocktail recipe web. If I search for the name of the cocktail, I want the cocktail to appear. The error message shown to me is as follows.
"TypeError: Cannot read property 'filter' of undefined"
Please tell me how to solve this problem. I'm a beginner. Is there a problem with my code?
This is Search.jsx
import React, { useState, useEffect } from "react";
import useFetch from "../Components/useFetch";
const Searchs = () => {
const url =
"https://www.thecocktaildb.com/api/json/v1/1/search.php?s=margarita";
const [data] = useFetch(url);
const [searchTerm, setSearchTerm] = useState("");
const [searchResults, setSearchResults] = useState([]);
const handleChange = (event) => {
setSearchTerm(event.target.value);
};
useEffect(() => {
const results = data.drinks.filter(({ strDrink }) =>
data.strDrink.toLowerCase().includes(searchTerm)
);
setSearchResults(results);
}, [searchTerm]);
return (
<Wrapper>
<Search
type="text"
placeholder="재료 또는 이름을 검색하세요"
value={searchTerm}
onChange={handleChange}
/>
<ul>
{searchResults.map((item) => (
<li>{item}</li>
))}
</ul>
</Wrapper>
);
};
export default Searchs;
This is useFetch.jsx
import { useState, useEffect } from "react";
function useFetch(url) {
const [data, setData] = useState([]);
const [loading, setLoading] = useState(true);
async function fetchUrl() {
const response = await fetch(url);
const json = await response.json();
setData(json);
setLoading(false);
}
useEffect(() => {
fetchUrl();
}, []);
return [data, loading];
}
export default useFetch;
This is JSON
{
"drinks": [
{
"idDrink": "12784",
"strDrink": "Thai Iced Coffee",
"strCategory": "Coffee / Tea",
"strIBA": null,
"strAlcoholic": "Non alcoholic",
"strGlass": "Highball glass",
"strDrinkThumb": "https://www.thecocktaildb.com/images/media/drink/rqpypv1441245650.jpg",
"strIngredient1": "Coffee",
"strIngredient2": "Sugar",
"strIngredient3": "Cream",
"strIngredient4": "Cardamom",
"strMeasure1": "black",
"strMeasure3": " pods\n",
"strImageAttribution": null,
"strCreativeCommonsConfirmed": "No",
"dateModified": "2015-09-03 03:00:50"
}
]
}
Do null check before filter(), Your API might return null/undefined you should handle such cases.
Bonus: onChange={handleChange} don't directly call API on change, add some denounce check, to improve performance.
useEffect(() => {
const results = data?.drinks?.filter(({ strDrink }) =>
data.strDrink.toLowerCase().includes(searchTerm)
) ?? [];
setSearchResults(results);
}, [searchTerm]);
you did many mistakes in this code look below how I did it
here you can find sandbox URL where you can see live working code
https://codesandbox.io/s/boring-tesla-hoc11?file=/src/App.js:75-1141
I have changed your wrapper to input element for testing you can revert it back
const Searchs = () => {
const url =
"https://www.thecocktaildb.com/api/json/v1/1/search.php?s=margarita";
const [searchTerm, setSearchTerm] = useState("");
const [searchResults, setSearchResults] = useState([]);
const [data, setData] = useState([]);
const [loading, setLoading] = useState(true);
const handleChange = (event) => {
setSearchTerm(event.target.value);
};
useEffect(() => {
async function fetchUrl() {
const response = await fetch(url);
const json = await response.json();
setData(json);
setLoading(false);
const results = data.drinks.filter(({ strDrink }) =>
strDrink.toLowerCase().includes(searchTerm)
);
setSearchResults(results);
}
fetchUrl();
}, [searchTerm]);
return (
<>
<input
type="text"
placeholder="재료 또는 이름을 검색하세요"
value={searchTerm}
onChange={handleChange}
/>
<ul>
{searchResults.map((item,index) => (
<li key={index}>{item.strDrink}</li>
))}
</ul>
</>
);
};
It seems like your API is returning nothing. You should add a check to see if anything is returned from API:
ALSO: you have to include data which you get from useFetch to the useEffect dependencies, otherwise it's value won't be changed in each useEffect call:
useEffect(() => {
const results = data?.drinks?.filter(({ strDrink }) =>
data.strDrink.toLowerCase().includes(searchTerm)
) ?? [];
setSearchResults(results);
}, [searchTerm, data]);