0

I'm attempting to get the subtopics data, so first I have to get the courses in which a user has registered, then for each course I get the chapters, then for each chapter, I get the topics, and finally, I get the subtopics from each topic and push them all into the temp array. However, when I tried to print it in the second useEffect, it returned an empty array despite printing in the FetchSubtopics function.

import React from "react";
import { useEffect, useState } from "react";
import { useLocation, Link } from "react-router-dom";
import { baseURL } from "../../../Apis";
 
function Lectures() {

let temp = [];
const [courses, setcourses] = useState(()=> {return null});
 useEffect(() => {
 const fun = async (e) => {
  const response = await fetch(`${baseURL}/user/profile`, {
    method: "GET",
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${localStorage.getItem("token")}`,
    },
  });
  const json = await response.json();
  if (json.success) {
    setcourses(json.data.courses);
  }
};
fun();
}, []);

if(courses){
  courses.map((course)=>{
  return FetchChapter(course._id);  
})
}

// Now fetching chapters of each course
function FetchChapter(id){
const fun = async (e) => {
const response = await fetch(`${baseURL}/course/${id}?queryParam=0`, {
  method: "GET",
  headers: {
    "Content-Type": "application/json",
    Authorization: `Bearer ${localStorage.getItem("token")}`,
  },
});
const json = await response.json();
json.data.chapters.map((chapter)=>{
  return FetchTopic(id,chapter._id);
});
 
};
fun();
}
 
function FetchTopic(id,chapter_id){
const fun = async (e) => {
const response = await fetch(`${baseURL}/course/${id}/? 
 queryParam=1&chapterID=${chapter_id}`, {
    method: "GET",
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${localStorage.getItem("token")}`,
    },
  });
  const json = await response.json();
    json.data.chapter.topics.map((topics)=>{
          topics.subTopics.map((topic)=>{
            FetchSubtopic(topic)
          })
    });     
 }
 fun()
}

function FetchSubtopic(topic){
 const fun = async (e) => {
 const response = await fetch(`${baseURL}/course/subtopics/${topic._id}`, {
  method: "GET",
  headers: {
    "Content-Type": "application/json",
    Authorization: `Bearer ${localStorage.getItem("token")}`,
  },
 });
 const json = await response.json();
  if(json.contentType == 0){
    temp.push(topic);          // pushing all the subtopics into temp array
    console.log(temp);   
  }
  }
  fun()
  }

 const [State, setState] = useState([]);

useEffect(() => {
console.log(temp);  // Why empty?????
setState(temp);
}, []);

return (<> some code... </>)

}
export default Lectures;
Ajit Kumar
  • 21
  • 3

2 Answers2

1

Because of the JavaScript's event loop the push method won't work in your scenario. Duo to the async behavior of your functions the function fires off before the stack updates your array.

Yogev D.
  • 118
  • 4
  • Is there is a way that i could resolve the issue so that i am able to access the temp array data or something like another way – Ajit Kumar Jul 04 '22 at 07:12
  • I'm not 100% sure what you're trying to do here - but you might want to use Redux or ContextAPI to better manage your state while fetching data from the server. Also - the useEffect hook only mutate the data AFTER the DOM has been completely loaded which might also cause your problem. – Yogev D. Jul 04 '22 at 08:41
1

I think you should call setState(temp) from inside fun rather than inside an useEffect.

An useEffect with an empty array [] dependency is equivalent to componentDidMount.
Hence it's called as soon as the component is mounted & does not wait for the fetch to complete.

Nice Books
  • 1,675
  • 2
  • 17
  • 21