How does infinite scroll work in case of caching redis

Viewed 59

In case of no cache, infinite scroll works, but when you add cache code, the data repeats when pagination is finished. how can i solve. I am doing a clone project. I'm new to redis, I'd be very grateful if you could reply. I can't think of anything about it (: Backend my code

const searchpost = async (req, res) => {
      let perpage = 3;
      const value = req.query.q;
      const pageNumber = req.query.page;
    
      try {
        const redisPosts = await client.keys("Blog*");
        if (redisPosts.length > 0) {
          async.map(
            redisPosts,
            async function (redisPost) {
              const cacheBlog = await client.get(redisPost);
              let parseData = JSON.parse(cacheBlog);
              let job = { ...parseData };
    
              return job;
            },
            function (err, results) {
              if (err) throw err;
    
              res.status(200).json({ searcharticles: results });
            }
          );
        } else {
          const searcharticles = await Blog.find({
            $or: [
              { title: { $regex: value, $options: "i" } },
              { tag: { $regex: value, $options: "i" } },
              { Subtitle: { $regex: value, $options: "i" } },
            ],
          })
            .skip((pageNumber - 1) * perpage)
            .limit(perpage)
            .populate("authorId");
    
          async.map(
            searcharticles,
            async function (searcharticle) {
              let cacheKey = `Blog:` + uuidv4();
    
              await client.set(cacheKey, JSON.stringify(searcharticle));
              return searcharticles;
            },
            function (err, searcharticles) {
              if (err) throw err;
    
              res.status(200).json({ searcharticles });
            }
          );
        }
      } catch (err) {
        res.status(401).json({ message: "hata durumu oluştu" });
      }
    };

infinity scroll react code

export const SearchPost = (query, pageNumber) => {
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(false);
  const [blogs, setBlogs] = useState([]);
  const [hasMore, setHasMore] = useState(false);
  const [userInfo, setuserInfo] = useState();

  useEffect(() => {
    setBlogs([]);
  }, [query]);

  useEffect(() => {
    setLoading(true);
    setError(false);
    let cancel;
    axios({
      method: "GET",
      url: `/api/search`,
      params: { q: query, page: pageNumber },
      withCredentials: true,
      cancelToken: new axios.CancelToken((c) => (cancel = c)),
    })
      .then((res) => {
        console.log(res.data);
        setBlogs((prevBlog) => {
          return [
            ...new Set([...prevBlog, ...res.data.searcharticles.map((b) => b)]),
          ];
        });
        setHasMore(res.data.searcharticles.length);
        setLoading(false);
        setuserInfo(res.data.userInfo);
      })
      .catch((err) => {
        if (axios.isCancel(err)) return;
        setError(true);
      });

    return () => cancel();
  }, [query, pageNumber]);

  return { loading, error, blogs, hasMore, userInfo };
};


const [query, setQuery] = useState("");
  const [pageNumber, setPageNumber] = useState(1);
  const { ısAuthenticated } = useContext(AuthContext);

  const { blogs, hasMore, loading } = SearchPost(query, pageNumber);

  const observer = useRef();
  const lastBlogElementRef = useCallback(
    (node) => {
      if (loading) return;
      if (observer.current) observer.current.disconnect();
      observer.current = new IntersectionObserver((entries) => {
        if (entries[0].isIntersecting && hasMore) {
          //burda verıyı gecıp gecmedıgını kontrol etmelıyız
          setPageNumber((prevPageNumber) => prevPageNumber + 1);
        }
      });
      if (node) observer.current.observe(node);
    },
    [loading, hasMore]
  );

  function handleSearch(e) {
    setQuery(e.target.value);
    setPageNumber(1);
  }
1 Answers

I'm writing for those who encounter this problem, you don't need to do a for loop. You can do this by typing the number of pages into the key. The edited code is below.

const searchpost = async (req, res) => {
  let perpage = 3;
  const value = req.query.q;
  const pageNumber = req.query.page;
  const query = `Blog:` + "/" + pageNumber;
  try {
    let redisPosts = await client.get(query);

    if (redisPosts) {
      redisPosts = JSON.parse(redisPosts);
      res.status(200).json({ searcharticles: redisPosts });
    } else {
      const searcharticles = await Blog.find({
        $or: [
          { title: { $regex: value, $options: "i" } },
          { tag: { $regex: value, $options: "i" } },
          { Subtitle: { $regex: value, $options: "i" } },
        ],
      })
        .skip((pageNumber - 1) * perpage)
        .limit(perpage)
        .populate("authorId");

      let cacheKey = query;

      await client.set(cacheKey, JSON.stringify(searcharticles));
      res.status(200).json({ searcharticles });
    }
  } catch (err) {
    res.status(401).json({ message: "hata durumu oluştu" });
  }
};
Related