How to set counter to count number of view on each post - reactjs

I sat a counter which is counting the total number of visit on my post instead of counting the views on per post. here is the code below:
const ViewPost=()=>{
const [user,setUser] = useState({
title:"",
body:"",
date:""
});
const {id} = useParams();
const [count,setCount]=useState(parseInt(localStorage.getItem('count')));
console.log(count)
useEffect(()=>{
loadUser();
},[])
const IncNum=()=>{
setCount(count+1);
}
localStorage.setItem('count',count)
const loadUser = async ()=>{
const result = await axios.get(`http://localhost:3004/posts/${id}`,IncNum());
setUser(result.data);
// console.log(result.data)
} ;
return(
<div>
<span> {(user.title) ==='' ?<ErrorPage /> :
<div className="container py-4">
<Link className="btn btn-primary" to= "/blog"> Back to home</Link>
<h1 className="display-4"> Post: {id}</h1>
<hr/>
<ul className="list-group w-100">
<li className="list-group-item"> Title:{user.title}</li>
<li className="list-group-item"> Body:{renderHtml(user.body)}</li>
<li className="list-group-item"> Date:{user.date}</li>
</ul>
<h1> {/*count*/} </h1>
</div>
}</span>
</div>
)
}
export default ViewPost;

Related

How to get a particular Index from a shuffled array

I've been working on a quiz app using NextJs and after figuring out how to work around the hydration issue in Nextjs, Now I'm stuck trying to figure out how to keep track of a value in the array.
export default function quiz({ questions }) {
const link = `https://the-trivia-api.com/api/questions`;
const [number, setNumber] = useState(0);
const [quizData, setQuizData] = useState(questions);
const [numbering, setNumbering] = useState(1);
const [initialRenderComplete, setInitialRenderComplete] = useState(false);
console.log(quizData[number].correctAnswer);
const oldArray = [...quizData[number].incorrectAnswers, quizData[number].correctAnswer];
oldArray.push(quizData[number].correctAnswer); //Here I pushed the correct answer and incorrect answer into a single array.
const newArray = [...new Set(oldArray)]; // 'newArray' is the new array containing all the four options.
const increase = () => {
setNumber(number + 1);
setNumbering(numbering + 1);
};
const decrease = () => {
setNumber(number - 1);
setNumbering(numbering - 1);
};
useEffect(() => {
setInitialRenderComplete(true);
}, []);
if (!initialRenderComplete) {
return null;
} else {
newArray.sort(() => (Math.random() > 0.5 ? 1 : -1)); // Here i shuffled the newArray, So the correct and incorrect answer is shuffled.
return (
<div className={styles.container}>
<div className={styles.profile}>
<div className={styles.mainProfile}>
<div className={styles.profilePic}>
<img src={image} alt="img" />
</div>
<h2>{state} </h2>
</div>
</div>
<div className={styles.main}>
<h2>
{numbering}. {questions[number].question}{" "}
</h2>
<div className={styles.list}>
<ul className={styles.list1}>
<div className={styles.flex}>
<h3>A. </h3>
<button>
<li>{newArray[1]} </li>
</button>
</div>
<div className={styles.flex}>
<h3>B. </h3>
<button>
{" "}
<li> {newArray[0]} </li>
</button>
</div>
</ul>
<ul className={styles.list2}>
<div className={styles.flexOption}>
<h2>C. </h2>
<button>
<li>{newArray[3]}</li>
</button>
</div>
<div className={styles.flexOption}>
<h2>D. </h2>
<button>
<li>{newArray[2]} </li>
</button>
</div>
</ul>
</div>
<div className={styles.btnStyle}>
<button onClick={decrease} className={styles.prev}>
Previous{" "}
</button>
<button onClick={increase} className={styles.next}>
Next{" "}
</button>
</div>
</div>
</div>
);
}
}
//Here is my Api Call
export const getStaticProps = async () => {
const data = await Axios.get("https://the-trivia-api.com/api/questions");
// const data = req;
const initialData = data.data;
return {
props: {
// question: data.data[indexing],
questions: initialData,
},
};
};
Now I'm stuck on how to keep track of which is the correct or incorrect Option onClick of the button, I figured I could maybe keep track of the index of the correct answer in the array but I don't think it would work and I can't figure out how to do it, Thanks in Advance.

Pagination with Firebase v9 and React not working

I'm trying to build a page that paginates all the data from a collection, however I can't seem to figure out how to do it and I haven't found anyone who's done it either.
I've tried to get the documentList.length, but that also isn't working.
function Sessions() {
const location= useLocation();
const user= location.state.user;
const [sesList, setSesList] = useState([]);
const subRef=collection(db, 'Users',user,'Sessions');
let q = query(subRef,orderBy('time','desc'),limit(5));
const DocumentSnapshot=getDocs(q);
const last= DocumentSnapshot[DocumentSnapshot.length-1]
const next=()=>{
return q=query(subRef,orderBy('time','desc'), startAfter(last), limit(5))
}
const prev=(first)=>{
return q=query(subRef, orderBy('time','desc'), endBefore(first['time','desc']), limitToLast(5))
}
useEffect(() => { //loads all the tenants
onSnapshot(q, (snapshot) => {
setSesList(
snapshot.docs.map((doc) => ({ ...doc.data(), id: doc.id }))
);
});
}, []);
return (
<div className='Sessions'>
<Sidebar className='nav'
L1={<Link to='/Dashboard' state={{user:user}}>Dashboard</Link>}
L2={<Link to='/Sessions' state={{user:user}}>Sessions</Link>}/>
<div className="bod">
<div className="startCard1">
<h1>Sessions</h1>
</div>
<div className="Recent">
<h1>Your Sessions:</h1>
<div className="recSes">
{sesList.map((REC)=>{
return(
<div className="rowCard">
<div className="rowCardTitle">
<h3> Subject: {REC.subject}</h3>
</div>
<div className="WTime">
<h3>Work Minutes: {REC.WorkTime}</h3>
</div>
<div className="BTime">
<h3> Break Minutes: {REC.BreakTime}</h3>
</div>
<div className="Atime">
<h3>Date: {REC.time}</h3>
</div>
</div>
)
})}
</div>
</div>
<div className="buttoninlin">
<button className='Gobtn1'>Previous </button>
<button className='Gobtn1' onClick={next}>Next</button>
</div>
</div>
</div>
)
}
export default Sessions
expected result: next button shows next documents, back button shows previous documents

Sanity posts display all categories, not just ones associated with post

I am working on making a blog using React and Sanity, and I want to display the categories associated with each post underneath each post. I am able to display the categories, but it displays all categories, not just the ones associated with each specific post. How can I make it so each posts displays only the categories associated with it?
Here is my code:
import React, { useEffect, useState } from 'react'
import client from '../client'
import BlockContent from '#sanity/block-content-to-react'
import { Link } from 'react-router-dom'
function Main() {
const [posts, setPosts] = useState([])
useEffect(() => {
client.fetch(
`*[_type == "post"] {
title,
slug,
body,
author,
mainImage {
asset -> {
_id,
url
},
alt
},
publishedAt,
"categories": categories[]->title
}`
).then((data) => setPosts(data))
.catch(console.error)
}, [])
return (
<div className='grid lg:grid-cols-3 md:grid-cols-2 gap-8 m-4 '>
<div>
{posts.slice(0, 1).map((p, i) => (
<Link to = {`/blog/${p.slug.current}`} className=''>
<article key = {p.slug.current} className=''>
<img src = {p.mainImage.asset.url} alt = {p.title} className='' />
<div>
<p className='font-bold text-xl text-secondary'>{p.title}</p>
<div className=''>
<p className='text-sm'>By Brandon Pyle | {new Date(p.publishedAt).toLocaleDateString()}</p>
{posts.map((c, i) => (
<p className='inline'>{c.categories}, </p>
))}
</div>
</div>
</article>
</Link>
))}
</div>
<div className='my-[-16px]'>
{posts.slice(1, 4).map((p, i) => (
<Link to = {`/blog/${p.slug.current}`} className='col-start-2'>
<article key = {p.slug.current} className='flex my-4'>
<img src = {p.mainImage.asset.url} alt = {p.title} className='w-auto h-auto max-h-[80px]' />
<div>
<p className='font-bold text-xl text-secondary'>{p.title}</p>
<p className='text-sm'>By Brandon Pyle | {new Date(p.publishedAt).toLocaleDateString()}</p>
<div>
{posts.map((c, i) => (
<p className='inline'>{c.categories}, </p>
))}
</div>
</div>
</article>
</Link>
))}
</div>
</div>
)
}
export default Main
Thanks to #cfm I was able to find a solution:
Your query looks good. But you are mapping posts again inside the .map
of posts. I would expect you to do p.categories.map in the inner map,
if you wanted only this posts categories titles.
As he suggested, I simply switched posts.map to p.categories.map, and this fixed the problem! Here is the full fixed code:
import React, { useEffect, useState } from 'react'
import client from '../client'
import BlockContent from '#sanity/block-content-to-react'
import { Link } from 'react-router-dom'
function Main() {
const [posts, setPosts] = useState([])
useEffect(() => {
client.fetch(
`*[_type == "post"] {
title,
slug,
body,
author,
mainImage {
asset -> {
_id,
url
},
alt
},
publishedAt,
"categories": categories[]->title
}`
).then((data) => setPosts(data))
.catch(console.error)
}, [])
return (
<div className='grid lg:grid-cols-3 md:grid-cols-2 gap-8 m-4 '>
<div>
{posts.slice(0, 1).map((p, i) => (
<Link to = {`/blog/${p.slug.current}`} className=''>
<article key = {p.slug.current} className=''>
<img src = {p.mainImage.asset.url} alt = {p.title} className='' />
<div>
<p className='font-bold text-xl text-secondary'>{p.title}</p>
<div className=''>
<p className='text-sm'>By Brandon Pyle | {new Date(p.publishedAt).toLocaleDateString()}</p>
{p.categories.map((c, i) => (
<p className='inline'>{c}, </p>
))}
</div>
</div>
</article>
</Link>
))}
</div>
<div className='my-[-16px]'>
{posts.slice(1, 4).map((p, i) => (
<Link to = {`/blog/${p.slug.current}`} className='col-start-2'>
<article key = {p.slug.current} className='flex my-4'>
<img src = {p.mainImage.asset.url} alt = {p.title} className='w-auto h-auto max-h-[80px]' />
<div>
<p className='font-bold text-xl text-secondary'>{p.title}</p>
<p className='text-sm'>By Brandon Pyle | {new Date(p.publishedAt).toLocaleDateString()}</p>
<div>
{p.categories.map((c, i) => (
<p className='inline'>{c}, </p>
))}
</div>
</div>
</article>
</Link>
))}
</div>
</div>
)
}
export default Main

Link same page with different parameters react using link

I want refresh page and send data using link but it don't work
I am using a link to send me to same page but with different parameters but it is not work and it is not refresh ... what I should do?
When I click the link it change from link but it is not change in the page and does not refresh with the data does not change. What should I do?
<Link to={`/NewDetails/${news[arr].id}`}> read more </Link>
the js I'm using is
const NewDetails = () => {
const { id } = useParams();
const [newsDetail, setNewsDetail] = useState("");
useEffect(() => {
async function fetchMyAPI() {
let news = await onGetNewsById(id);
setNewsDetail(news);
}
fetchMyAPI();
}, []);
const [news, setNews] = useState("");
useEffect(() => {
async function fetchMyAPI() {
let news = await onGetNews();
setNews(news);
}
fetchMyAPI();
}, []);
const last_num = news.length;
const last_3_num = news.length - 3;
return (
<div>
<div>
<NavBar />
</div>
<div className="row">
<div className="NewsDetails_Section">
<div className="text-center">
<div className="imageDetailsBackground">
<img className="ImageNewsDetails" src={Wallet} alt="bankimage" />
</div>
</div>
<div className="text-center" dir='rtl'>
<h1> {newsDetail.title} </h1>
</div>
<div className="Body_news_Details">
<p className="text-center"> {newsDetail.content} </p>
</div>
<div>
<div className="News_Details_" dir="rtl">
{Object.keys(news.slice(last_3_num, last_num), NewsImage.slice(last_3_num, last_num)).map(arr => (
<div className="NewSection_details" key={news[arr].id}>
<div className="ImageNews_Details">
<img className="ImageNews_Details" src={NewsImage[arr]} alt="bankimage" />
</div>
<div className="HeaderNews_Details">
<h4>{news[arr].title} </h4>
</div>
<div className="bodynews_details">
<p> {news[arr].content.slice(0, 100)}... </p>
</div>
<div className="ButtonNews_Details">
{/*
<Link Redirect push to={`/NewDetails/${news[arr].id}`}> */}
<Link to={`/NewDetails/${news[arr].id}`}> read more</Link>
</div>
</div>))}
</div>
</div>
</div>
</div>
</div>
);
}

react hooks : Uncaught TypeError: data.posts.map is not a function

I'm trying to make a list of jokes but it is saying " TypeError: data.posts.map is not a function ".
I used before same code but different API and it was working.
In console it is showing those posts but on app i get error saying that " data.posts.map "
Can anyone help me?
Thanks
This is my code:
import React, { useState, useEffect } from 'react';
import axios from 'axios';
const PostArea = () => {
const [like, showLike] = useState(false);
const [color, setColor] = useState('#000');
const likePrint = () => {
showLike(!like);
}
const [data, setPost] = useState({ posts: [] });
useEffect(() => {
const fetchData = async () => {
const result = await axios('https://sv443.net/jokeapi/v2/joke/Any?blacklistFlags=nsfw,religious,political,racist,sexist&idRange=0-40');
console.log({ posts: result.data });
setPost({ posts: result.data });
};
fetchData();
}, []);
return (
<div>
{data.posts && data.posts.map(({ id, setup, delivery, category }) => {
return (
<div key={id} className="post">
<div className="header">
<a>
<img src="https://unsplash.it/40" alt=" title" />
<div>
<span className="detail">Category :{category}</span>
</div>
</a>
</div>
<div className="content">
<p>
{setup}
</p>
<p>
{delivery}
</p>
</div>
<div className="footer">
<ul>
<li>
<a style={{ color: color }} onClick={() => { likePrint(!like); setColor('#2274a5') }}>
<i className="fas fa-heart"></i>
</a>
</li>
<li>
<a>
<i className="fas fa-comment"></i>
</a>
</li>
<li>
<a>
<i className="fas fa-share-alt-square"></i>
</a>
</li>
</ul>
</div>
</div>
);
})}
</div>
);
}
export default PostArea;
Error : Uncaught TypeError: data.posts.map is not a function
I was looking at the response from the https://sv443.net/jokeapi/v2/joke/Any?blacklistFlags=nsfw,religious,political,racist,sexist&idRange=0-40, and it seems like it is returning an object, rather an array, which is the expected type of data.post.
I guess you would want to include this object as part of the post array?
const fetchData = async () => {
const result = await axios('https://sv443.net/jokeapi/v2/joke/Any?blacklistFlags=nsfw,religious,political,racist,sexist&idRange=0-40');
setPost({ posts: [result.data] });
};

Resources