skip to Main Content

Hello I have Problem in my mern stack app

first of all I added the limit and skip value into my backend node js like this code

const getPosts = async (req, res) => {
  const { userId } = req.params;
  const limitValue = req.query.limit || 10;
  const skipValue = req.query.skip || 0;
  const posts = await Post.find(userId ? { bookmarks: userId } : {})
    .sort({ createdAt: -1 })
    .populate("author")
    .populate("tags")
     .limit(limitValue)
     .skip(skipValue)


  if (!posts) res.status(204).json("No posts found");
  else {
    res.status(200).json(posts.map((post) => post.toObject({ getters: true })));
  }
};

then I come to my react app and added the infinity scroll . but like code below

but there is one problem . it just loop the first 10 post from database instead of fetching new posts from database

this is my react code

const PostsList = ({  filteredTag, toInvalidate, enableImages = true }) => {
  const advertise =async () => {
    
    window?.EventBus?.emit('reset-ads')
    
  }
   useEffect(() => {
   advertise()
  }, []);









  const [posts, setArticles] = useState(null);

  useEffect(() => {
    const fetchAgain = async () => {
      if (posts != null) {
        // await fetch(`${process.env.BASE_URL}/posts?skip=10`)
        await fetch("http://127.0.0.1:5000/posts?skip=10")
        .then((res) => res.json())
          .then((result) => setArticles([...posts, ...result]));
      }
    };

    const handleScroll = () => {
      const html = document.documentElement;
      const body = document.body;
      const windowheight =
        "innerHeight" in window ? window.innerHeight : html.offsetHeight;

      const docHeight = Math.max(
        body.scrollHeight,
        body.offsetHeight,
        html.clientHeight,
        html.scrollHeight,
        html.offsetHeight
      );

      const windowBottom = windowheight + window.pageYOffset;
      if (windowBottom >= docHeight) {
        console.log("we reached the bottom");
        fetchAgain();
      }
    };

    window.addEventListener("scroll", handleScroll);

    return () => window.removeEventListener("scroll", handleScroll);
  }, [posts]);

  useEffect(() => {
    setTimeout(async () => {
      // const res = await fetch(`${process.env.BASE_URL}/posts`)
      const res = await fetch("http://127.0.0.1:5000/posts")
      const data = await res.json();

      setArticles(data);
      console.log(data);
    }, 2000);
  }, []);














  



  return (
    <Wrapper>
       {posts?.length > 0 ? (
        posts.map((post, i) => (
         <><><Post
            post={post}

            isFirstPost={enableImages &&  i++}
            filteredTag={filteredTag}
            key={nanoid()}
            toInvalidate={toInvalidate} />
            <Advertise />
            </></>
        ))
      ) :
      <LoadingSpinner />
      // (
        
      //   <Placeholder />
        
      // )
      }        
    </Wrapper>
  );
};

If possible some one answer me I tried every solutions . it just infinity scroll is working . but not fetching new post after first 10 post

can not understand why this happening because of the backend code or my react code not working

2

Answers


  1. The error is happening because of your db query, as your query first find the result, then limit the size of result to limit and later on it skips the first few value of result depending on skip size.
    Your Query should be

    const getPosts = async (req, res) => {
      const { userId } = req.params;
      const limitValue = req.query.limit || 10;
      const skipValue = req.query.skip || 0;
      const posts = await Post.find(userId ? { bookmarks: userId } : {})
        .sort({ createdAt: -1 })
        .populate("author")
        .populate("tags")
         .skip(skipValue) //this should be above
         .limit(limitValue) //after skipping
         
    
    
      if (!posts) res.status(204).json("No posts found");
      else {
        res.status(200).json(posts.map((post) => post.toObject({ getters: true })));
      }
    };
    

    Also, in your front-end code, this part need correction

    useEffect(() => {
        const fetchAgain = async () => {
          if (posts != null) {
            // await fetch(`${process.env.BASE_URL}/posts?skip=10`)
            await fetch("http://127.0.0.1:5000/posts?skip=10")
            .then((res) => res.json())
              .then((result) => setArticles([...posts, ...result]));
          }
        };
    

    As it will loop through only first 10 post, because val of skip is fixed. Instead it should go like:

    var skip = 10;
    useEffect(() => {
        const fetchAgain = async () => {
          if (posts != null) {
            // await fetch(`${process.env.BASE_URL}/posts?skip=10`)
            await fetch(`http://127.0.0.1:5000/posts?skip=${skip}`)
            .then((res) => res.json())
              .then((result) => { 
                 setArticles([...posts, ...result]) 
                 skip += 10
              });
          }
        };
    

    Here skip is value defined above and starts with 10. Also this code needs some more work, removing boilerplate code but to do that I will need full code.

    This part is more of a recommendation,as you can improve the fetching system using IntersectionObserver as I also used this. To know more about it you can search on youtube there are some great videos.

    Login or Signup to reply.
  2. I think you are hardcoding the value of the skip to 10. That is why each time it calls the fetchAgain function, it only skip the first 10 posts. Instead of this you can use the length of the posts to get the skip value like the following code👇

    const fetchAgain = async () => {
      if (posts != null) {
       let skip = posts.length;
        // await fetch(`${process.env.BASE_URL}/posts?skip=10`)
        await fetch(`http://127.0.0.1:5000/posts?skip=${skip}`)
        .then((res) => res.json())
          .then((result) => setArticles([...posts, ...result]));
      }
    };
    

    To limit the posts you can use limit=10.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search