Reactjs UseState & UseEffect Messing - reactjs

Below is a code i am using to set state for some data:
const [loader, setLoader] = useState(true);
const [trendData, setTrend] = useState([]);
const [thisMonthData, setThisMonth] = useState([]);
useEffect(() => {
graphData();
}, [loader]);
async function graphData() {
await getRequest(process.env.REACT_APP_apiUrl + ':0000/abc/xyz').then( (response) => {
let series = [];
let months;
for (let index = 0; index < response.length; index++) {
months = response[index]['Month'].split(',');
series.push(response[index]['Useres'].split(','));
}
setTrendMonth(series);
setThisMonthData(series);
console.log(thisMonthData);
setLoader(false);
});
}
And now i am attaching a response getting in console.log(thisMonthData); this. I have tried everything, including thisMonthData in useEffect and other state keys. But everytime data is going blank or missing values.
Whats wrong here.
enter image description here
enter image description here

You are mixing await and then, also try to log thisMonthData when they are changed with a useEffect:
useEffect(() => {
graphData();
}, [loader]);
useEffect(() => {
console.log(thisMonthData);
}, [thisMonthData]);
async function graphData() {
try {
const response = await getRequest(
process.env.REACT_APP_apiUrl + ':0000/abc/xyz'
);
let series = [];
let months;
for (let index = 0; index < response.length; index++) {
months = response[index]['Month'].split(',');
series.push(response[index]['Useres'].split(','));
}
setTrendMonth(series);
setThisMonthData(series);
setLoader(false);
} catch (err) {
console.log(err);
}
}

Hi Sandeep Singh,
Does the function getRequest() use axios or already does the .json() in some step? Like in the ex:
fetch(myRequest)
.then((response) => response.json())
.then((data) => {/***/}

Related

useEffect didnt run

So i have this function that i want to run once when the app start. This function task is to create userId then i will run another function to fetch data from firebase with the userId that created before. But the fetch function didn't start or it didnt do the task well, there is no sign of error, that's what make it more confusing. If i press the fetch function by button it work correctly.
the state
const [task, setTask] = useState(); // bisa di sebut sebagai controller text input
const [taskItems, setTaskItems] = useState([]); // state untuk list task
const [userId, setUserId] = useState();
const [isLoading, setIsLoading] = useState(true);
const baseUrl =
'https://react-http-post-RANDOM_KEY-default-rtdb.firebaseio.com/task/' + userId;
this is function to create userId function on init app
const handleCreateUser = async () => {
setIsLoading(true);
try {
const value = await AsyncStorage.getItem('userId');
if (value !== null) {
setUserId(value);
} else {
const uniqueId = makeid(6);
await AsyncStorage.setItem('userId', 'user' + uniqueId);
setUserId('user' + uniqueId);
}
await fetchDatabase();
} catch (error) {
console.log('errorrr AsyncStorage' + error);
}
setIsLoading(false);
};
this is function to fetch data from firebase
const fetchDatabase = async () => {
console.log('infinite looping');
try {
const response = await fetch(baseUrl + '.json');
if (!response.ok) {
throw new Error('Something went wrong!');
}
const data = await response.json();
// looping Map/Object dengan key sebagai indexnya
const loadedTask = [];
for (var id in data) {
loadedTask.push({
key: id,
text: data[id].text,
isComplete: data[id].isComplete,
});
}
setTaskItems(loadedTask);
} catch (error) {
setError(error.message);
}
};
this is how i call the useEffect
useEffect(() => {
handleCreateUser();
}, []);
The first thing I see is that you are not using await correctly. It should be before fetchDatabase(); function that is inside handleCreateUser like so:
await fetchDatabase();
The word await is there when you have to call an asynchronous function and you have to wait for this function to be completed.
Edit
To use only one useEffect you can check if your fetch function received your data by:
// or whatever statusCode you get when the data are present
if(reponse.statusCode === 200) {
// the await is not needed because it is present for the reponse abov
const data = response.json();
// looping Map/Object dengan key sebagai indexnya
const loadedTask = [];
for (var id in data) {
loadedTask.push({
key: id,
text: data[id].text,
isComplete: data[id].isComplete,
});
}
setTaskItems(loadedTask);
}
i got the answer, by using 2 useEffect
useEffect(() => {
handleCreateUser();
}, []);
useEffect(() => {
fetchDatabase();
}, [userId]);

the same variable has a different value in the code

const [arrUserID, setArrUserID] = useState([])
const fetchUser = async () => {
try {
const owner = await axios({
url: `${baseUrl}/addcryptos/owner/${userid}`,
method: 'get'
})
const { events } = owner.data
for (let i = 0; i < events.length; i++) {
const reducer = (accumulator, curr) => accumulator + curr;
setArrUserID(arrUserID.push(events[i].id)) // return id of 'events' in array [1, 1027, 1027, 3087]
console.log(arrUserID.toString()) // return 1,1027,1027,3087
}
}
catch (err) {
console.log(err)
}
}
const problem = useEffect(() => {
(async () => {
if (arrUserID.toString() !== '')
try {
const data = await axios({
url: `http://myurl/yes?id=${arrUserID.toString()}`,
method: 'get'
})
console.log(arrUserID) //THERE IS A PROBLEM -> return 4 because my array length is 4 but it's expected to be "1,1027,1027,3087"
} catch (error) {
console.log(error)
}
})();
}, []);
so i don't understand why when i console.log my "arrUserID" is one time = [1027, 1, 453 ....] and one time egal to array.length ?
if somebody know what is the problem that would be great beacause i don't have any idea
thanks
the way to set a new state for an array is through spread syntax.
When you do:
setArrUserID(arrUserID.push(events[i].id))
you're setting the value of arrUserId to be the 4 because .push() returns the new length of the array, see here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push
Try doing:
setArrUserID([...arrUserId, events[i].id])

ReactJs is not reading map function inside useEffect

I want to fetch 3 different things from firestore, hence have applied 3 useEffect in my code, out of which my react is not reading the map function inside 3rd useEffect. Here this map function in 3rd useEffect is not working
Code:
1st useEffect:
useEffect(() => {
var applications = [];
const hospitals = [];
const studentId = [];
const details = [];
firebaseConfig
.firestore()
.collection("counselor")
.doc(currentUser.uid)
.collection("studentDetails")
.get()
.then((snapshot) => {
snapshot.docs.forEach((detail) => {
let currentID = detail.id;
let appObj = { ...detail.data(), ["id"]: currentID };
details.push(appObj);
details.push(detail.data());
});
setDetails(details);
});
}, []);
2nd useffect:
useEffect(() => {
const item = [];
details.map((detail) => {
console.log(detail.id);
firebaseConfig
.firestore()
.collection("counselor")
.doc(currentUser.uid)
.collection("studentDetails")
.doc(detail.id)
.collection("studentApplications")
.get()
.then((snapshot) => {
snapshot.docs.forEach((detail) => {
let currentID = detail.id;
let appObj = { ...detail.data(), ["id"]: currentID };
item.push(detail.data().applicationStatus);
setStudentId(item);
});
});
});
setDemo(item);
}, [details]);
3rd useeffect:
useEffect(() => {
demo.map((hii) => {
if (hii === "PaymentFormFilled") {
complete = complete + 1;
setCom(complete);
}
});
}, [demo]);
Your error is not clear: "react is not reading the map function...".
There could be several issues:
Is setDemo assigning a value to a state variable called demo? If not, your 3rd useEffect won't be triggered
What is the value assigned to demo? You might not run .map on it
Because setCom is async. state complete only update value when component re-render. Please move setCom to the outside loop. And using forEach instead map in this case.
useEffect(() => {
let newCount = complete;
demo.forEach((hii) => {
if (hii === "PaymentFormFilled") {
newCount += 1;
}
});
setCom(newCount);
}, [demo]);

Get an empty array when use array of objects in filter function React

I am new to react and try to get data from the database and view data in frontend. This is the code I tried.
function ViewPost() {
const { postId } = useParams();
console.log(postId);
const [post, setPost] = useState({});
useEffect(()=>{
getOnePost();
}, []);
useEffect(()=>{
if (post && post.location) {
console.log(post.location);
console.log(post.location.longitude);
console.log(post.location.latitude);
}
}, [post]);
const getOnePost = async () => {
try {
const response = await axios.get(`/buyerGetOnePost/${postId}`)
console.log(response);
const allPost=response.data.onePost;
setPost(allPost);
} catch (error) {
console.error(`Error: ${error}`)
}
}
console.log(post);
console.log(post.wasteItemList);
const [offers, setOffers] = useState([]);
useEffect(()=>{
getAllOffers();
}, []);
const getAllOffers = async () => {
await axios.get(`/viewPendingSellerOffers`)
.then ((response)=>{
const allNotes=response.data.existingOffers;
setOffers(allNotes);
})
.catch(error=>console.error(`Error: ${error}`));
}
console.log(offers);
const wasteItem = offers?.filter(wasteItems => wasteItems.status==='accepted' && wasteItems.wasteItemsListId===post?.wasteItemList?._id);
console.log(wasteItem);
}
When I call the first API I get these results. This is an image of results.
In the above image, there is a length 2 array of objects called as wasteItemList. Then I call the second API and get these results.
This image shows length 8 array of objects. Then I try to filter the data of these two arrays using this const wasteItem = offers?.filter(wasteItems => wasteItems.status === 'accepted' && wasteItems.wasteItemsListId === post?.wasteItemList?._id); code. But I get a length 0 empty array as the results of this filter function. But when I try an ID of a wasteItemList array
6112679258125b0418844368 instead of using this post?.wasteItemList?._id code I get the correct result. What is the problem here? How do I solve this problem?
Edited code:
function ViewPost() {
const { postId } = useParams();
const [post, setPost] = useState(undefined);
const [offers, setOffers] = useState(undefined);
useEffect(() => {
setPost(undefined);
axios
.get(`/buyerGetOnePost/${postId}`)
.then((resp) => setPost(resp.data.onePost))
.catch((err) => console.error(err));
}, [postId]);
useEffect(() => {
axios
.get(`/viewPendingSellerOffers`)
.then((response) => setOffers(response.data.existingOffers))
.catch((err) => console.error(err));
}, []);
useEffect(()=>{
if (post && post.location) {
console.log(post.location);
console.log(post.location.longitude);
console.log(post.location.latitude);
}
}, [post]);
console.log(post);
console.log(post?.wasteItemList);
console.log(offers);
const wasteItem = offers?.filter(wasteItems => wasteItems.status==='accepted' && wasteItems.wasteItemsListId===post?.wasteItemList?._id);
console.log(wasteItem);
}
useEffect runs asynchronously so your post will not be available
on your getAllOffers function which is located in your second
useEffect.
You will need to make your getOnePost() and getAllOffers() to
run synchronously within a single useEffect.
Or the problem is in your condition checks as I can't tell much only
by your given array picture.

ReactJs Unable to setSate in componentDidMount from async function

I'm calling an async function (getData()) in componentDidMount, and I'm trying to use this.setState with result of that function.
componentDidMount() {
let newData = getData();
newPodData.then(function (result) {
console.log('result', result)
this.setState({result})
})
}
However, I'm having issues getting my state to properly update. Some additional context - I'm trying to set my initial state with data I am receiving from a database. Is my current approach correct? What's the best way to accomplish this? Here's my async function for more context:
const getTeamData = async () => {
const getTeamMembers = async () => {
let res = await teamMemberService.getTeamMembers().then(token => { return token });
return res;
}
const getActiveTeams = async () => {
let res = await teamService.getActiveTeams().then(token => { return token });
return res;
}
const teamMemberResult = await getTeamMembers()
const activeTeamsResult = await getActiveTeams();
// get team member data and add to teamMember object
let teamMemberData = teamMemberResult.reduce((acc, curr) => {
acc.teamMembers[curr.id] = curr;
return acc;
}, {
teamMembers: {}
});
// get team ids and add to teamOrder array
let activeTeamsData = activeTeamsResult.map(team => team.id)
let key = 'teamOrder'
let obj = []
obj[key] = activeTeamsData;
const newObject = Object.assign(teamMemberData, obj)
return newObject;
}
export default getTeamData;
Changing the function inside the then handler to an arrow function should fix it. e.g:
componentDidMount() {
let newData = getData();
newPodData.then((result) => {
console.log('result', result)
this.setState({result})
})
}
But I'll like to suggest a better way to write that.
async componentDidMount() {
let result = await getData();
this.setState({result})
}

Resources