issue with Stripe_success _url with Multiple Destination Product Ids - reactjs

Please I need assistance with a code.
I have a Nextjs dynamic page as my 'stripe_success_url'
Initially I had one product 'courses' whose {id} is beign fetched in the router.query
however, i have created a new product 'ebook' whose {id} is also being fetched in the router.query
I edited the code to differentiate course ID and ebook ID but it is not working yet.
const StripeSuccess = () => {
// state
const [course, setCourse] = useState([]);
const [ebook, setEbook] = useState([]);
const router = useRouter();
const { id } = router.query;
useEffect(() => {
const fetchCourses = async () => {
const { data } = await axios.get('/api/courses');
setCourse(data);
//console.log(data);
};
fetchCourses();
}, [id]);
useEffect(() => {
const fetchEbooks = async () => {
const { data } = await axios.get('/api/ebooks');
setEbook(data);
//console.log(data);
};
fetchEbooks();
}, [id]);
useEffect(() => {
if (id === `${course._id}`) {
const successRequest = async () => {
const { data } = await axios.get(`/api/stripe-success/${id}`);
//console.log(data);
//console.log('SUCCESS REQ DATA', data);
router.push(`/user/course/${data.course.slug}`);
};
successRequest();
}
}, [id]);
useEffect(() => {
if (id === `${ebook._id}`) {
const successEbookRequest = async () => {
const { data } = await axios.get(`/api/stripe-ebooksuccess/${id}`);
//console.log(data);
//console.log('SUCCESS REQ DATA', data);
router.push(`/user/course/${data.ebook.slug}`);
};
successEbookRequest();
}
}, [id]);

Related

how to auto delete data after new data has been uploaded on firebase on react?

When a user updates their profile photo I want old data to be overwritten on firestore. I'm using firebase storage to store photos and upload firebase URL to restore database so
I tried filtering in on the front end side but I have multiple users to filter and there are a lot of duplicates
here is whole functionality of uploading data to firestore storage then updating firestore db and then pulling data with use
const [userImg, setUserImg] = useState()
const [image, setImage] = useState(null)
const [htlmImg, setHtmlImg] = useState(null)
const [url, setUrl] = useState(null)
const [userName, setUserName] = useState(null)
const [sureLoading, setSureLoading] = useState(false)
const [photoEdit, setPhotoEdit] = useState(false)
const handleImageChange = (e) => {
if (e.target.files[0]) {
setImage(e.target.files[0])
setHtmlImg(URL.createObjectURL(e.target.files[0]))
}
}
const uploadImg = () => {
const imageRef = ref(storage, `image${user.uid}`)
uploadBytes(imageRef, image)
.then(() => {
getDownloadURL(imageRef)
.then((url) => {
setUrl(url)
})
.catch((error) => {
console.log(error.message, 'error getting the image url')
})
setImage(null)
})
.catch((error) => {
console.log(error.message)
})
setSureLoading(true)
}
const handlePfpSubmit = async () => {
const { uid } = user
if (url !== null) {
try {
await addDoc(collection(db, 'user'), {
pfp: url,
userName,
uid,
timestamp: serverTimestamp(),
time: Date(),
})
if (!photoEdit) {
navigate('/test')
}
console.log('data send')
} catch (err) {
console.log(err)
}
}
}
const [displayName, setDisplayName] = useState(null)
const [displayPhoto, setDisplayPhoto] = useState(null)
const [userProfiles, setUserProfiles] = useState(null)
useEffect(() => {
const q = query(collection(db, 'user'),
orderBy('timestamp')).update()
const unsub = onSnapshot(q, (querySnapShot) => {
let photo = []
querySnapShot.forEach((doc) => {
photo.push({ ...doc.data(), id: doc.id })
})
console.log(photo)
console.log('data resived')
let userUid = photo
.filter((item) => {
if (user.uid === item.uid) {
return item.uid
}
})
.map((item) => {
const { pfp } = item
return pfp
})
setDisplayPhoto(
userUid.filter((val, index) => {
if (userUid.length - 1 <= index) {
return val
}
}),
)
let userUidName = photo
.filter((item) => {
if (user.uid === item.uid) {
return item.uid
}
})
.map((item) => {
const { userName } = item
return userName
})
let photoFilter = userUidName.filter((val, index) => {
if (userUidName.length - 1 <= index) {
return val
}
})
setDisplayName(photoFilter)
setUserProfiles(photo)
console.log(displayPhoto)
})
console.log('re render ? ')
return () => unsub()
}, [user])

Getting a undefined value when trying to match fetch results to people objects

Im working on a star wars api app. I am getting an array of people objects, 10 characters. Who all are their own object with different values. However homeworld, and species are urls. So I have to fetch them and store that data to the correct place. I figured out a way to get the homeworld values to each character. However when I try to do it with species I receive undefined. Would appreciate any help this has been kind of a pain thanks ahead of time !
const [people, setPeople] = useState([]);
const [homeWorld, setHomeWorld] = useState([]);
const [species, setSpecies] = useState([]);
const [nextPageUrl, setNextPageUrl] = useState("https://swapi.dev/api/people/");
const [backPageUrl, setBackPageUrl] = useState('');
const [test, setTest] = useState([]);
const fetchPeople = async () => {
const { data } = await axios.get(nextPageUrl);
setNextPageUrl(data.next);
setBackPageUrl(data.previous);
return data.results;
}
const backPage = async () => {
const { data } = await axios.get(backPageUrl);
setCharacters(data.results);
setNextPageUrl(data.next);
setBackPageUrl(data.previous);
}
// Get People
async function getPeople() {
const persons = await fetchPeople();
const homeWorldUrl= await Promise.all(
persons.map((thing) => axios.get(thing.homeworld)),
);
const newPersons = persons.map((person) => {
return {
...person,
homeworld: homeWorldUrl.find((url) => url.config.url === person.homeworld)
};
});
const newPersons2 = newPersons.map((person) => {
return {
...person,
homeWorld: person.homeworld.data.name
};
});
setPeople(newPersons2);
}
// Get Species
async function getSpecies() {
const persons = await fetchPeople();
const speciesUrl = await Promise.all(
persons.map((thing) => axios.get(thing.species)),
);
const newSwapi = persons.map((person) => {
return {
...person,
species: speciesUrl.find((info) => info.data.url === person.species)
};
});
setTest(newSwapi);
// const newPersons2 = newPersons.map((person) => {
// return {
// ...person,
// homeWorld: person.homeworld.data.name
// };
// });
}
useEffect(() => {
getPeople();
getSpecies();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []); ```
Species property of person is a array, so your getSpecies() should be like
async function getSpecies() {
const persons = await fetchPeople();
const speciesUrl = await Promise.all(
persons
.filter((thing) => thing.species.length)
.map((thing) => axios.get(thing.species[0]))
);
const newSwapi = persons.map((person) => {
return {
...person,
species: speciesUrl.find((info) => info.data.url === person.species[0])
};
});
setTest(newSwapi);
}

Api called twice next js

wondering how this could happen when this get call API twice. I'am using nextjs with typescript and using and design.
Below my code
const EditRoles = () => {
const router = useRouter();
const router = useRouter();
const { id } = router.query;
const [detail, setDetail] = useState();
const [rolePermission, setRolePermission] = useState([]);
const [pagination, setPagination] = useState<Params>({
page: 1,
row: 10,
});
const [loading, setLoading] = useState(false);
const [nextPage, setNextPage] = useState(0);
const getRolePermission = async (payload: { page?: number; row?: number; search?: string }) => {
if (id) {
setLoading(true);
const res = await httpService
.get(`${apiUrl.user}/v1/role-permission/${id}`, { params: payload })
.then((resp) => resp);
const rps = await res.data;
setLoading(false);
const roleP = rps.data.map((rp) => {
return { ...rp };
});
setRolePermission(rps.page === 1 ? roleP : [...rolePermission, ...roleP]);
setNextPage(rps.nextPage);
setPagination({ ...pagination, page: pagination.page + 1 });
console.log('this next page: ', rps.nextPage);
}
};
useEffect(() => {
getDetailRole();
getRolePermission({
...pagination,
});
form.setFieldsValue({
name: detail,
permissions: rolePermission,
});
}, [id, form, detail]);
return (
// ... HTML GOES HERE ... //
);
};
export default EditRoles;
And below are this result for the code. testing code
My question is, why this api called twice and the pagination sometimes breaking like the video?
Please help what is wrong with the code.
Thank you

Getting additional data in firebase/auth - onAuthStateChanged

I want to get extra data from a users collection in firestore when user loggs in. I do this in a useEffect function in a AuthContext. This is my code:
useEffect(() => {
const unsubscribe = onAuthStateChanged(auth, (user) => {
const fetchUserData = async () => {
if (!user) {
setCurrentUser(null);
setLoading(false);
return;
}
const userData = await fetchUserDataFromFirestore(user.uid);
setCurrentUser({ ...user, ...userData });
setLoading(false);
};
fetchUserData();
});
return unsubscribe;
}, [currentUser]);
This kind of works as I do get the data but messages are piling up in the console as can be seen in my screenshot:
The fetchUserDataFromFirestore function is implemented like this:
export const fetchUserDataFromFirestore = async (id) => {
const docRef = doc(db, "users", id);
const docSnap = await getDoc(docRef);
if (docSnap.exists) {
const userData = docSnap.data();
return userData;
}
return null;
};
What can I do about this?
For future reference this is how I did it
const [uid, setUid] = useState(null)
useEffect(() => {
const unsubscribe = onAuthStateChanged(auth, async (user) => {
if (user) {
setUid(user.uid)
} else {
setUid(null)
}
})
return () => {
unsubscribe()
}
}, [])
// set currentUser state
useEffect(() => {
if (uid) {
const userRef = doc(db, "users", uid)
getDoc(userRef)
.then((docSnapshot) => {
const data = docSnapshot.data()
setCurrentUser(data)
})
}
}, [uid])

React hooks - fetching data from api and passing to a component

So basically, I'm trying to fetch data from api and pass it to Component.
I create usePosition hook to get my positon from browser, and then get response from api. I really don't know how to wait with useEffect for my position, when i'm executing this code now I'm getting always log 'no position'.
const usePosition = () => {
const [error, setError] = useState(null);
const [position, setPosition] = useState();
useEffect(() => {
const geo = navigator.geolocation;
if(!geo) {
setError('Geolocation is not supported.');
return;
}
const handleSuccess = position => {
const { latitude, longitude } = position.coords;
setPosition({
latitude,
longitude
});
};
const handleError = error => {
setError(error.message);
};
geo.getCurrentPosition(handleSuccess, handleError);
}, []);
return { position, error };
}
function App() {
const {position, error} = usePositon();
const [weather, setWeather] = useState([]);
useEffect(() => {
if(position) {
const URL = `https://api.openweathermap.org/data/2.5/onecall?lat=${position.latitude}&lon=${position.longitude}&exclude=current,minutely,daily&units=metric&lang=pl&appid=${API_KEY}`;
const fetchData = async () => {
const result = await fetch(URL)
.then(res => res.json())
.then(data => data);
setWeather(result.hourly);
}
fetchData();
} else {
console.log('no position');
}
}, []);
return (
<div className="App">
<div>
<Swiper weather={weather}/>
</div>
</div>
)
}
It's all because of [] empty dependencies list down in App's useEffect. It runs exactly once on mount, when usePosition has not requested anything yet. And once it successes later and returns different { error, position } App does not react.
How to solve? Provide things as dependencies:
useEffect(() => {
if(position) {
const URL = `https://api.openweathermap.org/data/2.5/onecall?lat=${position.latitude}&lon=${position.longitude}&exclude=current,minutely,daily&units=metric&lang=pl&appid=${API_KEY}`;
const fetchData = async () => {
const result = await fetch(URL)
.then(res => res.json())
.then(data => data);
setWeather(result.hourly);
}
fetchData();
} else {
console.log('no position');
}
}, [position, error]);

Resources