PreventDefault inside of promise in React - javascript

I'm new to full stack development and I was looking for some pointers to how I can handle errors that return from a promise.
Basically, I have Game IDs stored in a MongoDB collection. When a user enters a Game ID, I want to check if the Game ID exists in the collection. If it doesn't, I don't want to link the user to a new page. If it does, the user should go to a new page.
Currently, my code doesn't prevent default and the user still goes to the "waitpage", even if I use event.preventDefault. I'm wondering how I can stop the user from going to this page.
This is the code I have right now in the frontend.
const onJoinGame = (event) => {
event.persist()
axios.get(`${BACKENDLINK}/rooms/${gameId}/room_available`)
.then((res) => {
if(res.data.Status == true){
axios.put(`${BACKENDLINK}/rooms/${gameId}/add_user`,
{
username: username
})
}
})
.catch((error) => {
event.preventDefault()
setErrorGameId("That game doesn't exist!")
})
}
And in the return statement, I use this function like so.
<Link to={`/${gameId}/waitpage`} onClick={(event) => onJoinGame(event)}>
<button className = "submit" id="joinGame">Join Game</button>
</Link>
In the backend, this is what my get function returns.
const roomAvailable = (req, res) => {
Room.findOne({roomId: req.params.id}, (err, result) =>{
if(!result){
res.status(400).json('Error: ' + err)
}
else{
res.json({'Status': true})
}
})
}
Any help would be greatly appreciated!

You can't prevent the event from a promise, you'll need to do that synchronously in the event handler.
If you do need to navigate to the other page after all, you'll have to do that manually using the imperative API of the router package (which provides Link) you're using.

Related

Shopify REST API Pagination using Node.js and Express

I'm facing an issue, using Product resource on Shopify REST Api : I need to display many products on a Node.js Express app, I've left the default limit at 50 and when I want to fetch the next page of 50 products when I click on a next or previous button (I use the nextPageUrl/prevPageUrl from the response headers) I get a 401 error if the request is made from the client-side because of CORS error
Then I tried to make the request on server-side, I've passed the link from client to server when hitting the next button for example but it still does not work
The documentation is not clear at all about the paginated request and nothing that i've done from the documentation now is correct, it just says "Make a GET request to the link headers" and voila
Anyone have done this before ?
Code below
protectedRouter.get('/inventory', async (req, res) => {
try {
const session = await Shopify.Utils.loadCurrentSession(req, res);
const client = new Shopify.Clients.Rest(session.shop, session.accessToken)
const result = await client.get({
path: 'products',
})
res.render('inventory', {
products: result,
})
} catch (error) {
throw error;
}
});
script(src="/scripts/pagination.js")
div.View
h3.title.my-4 Etat des stocks
div.row
div.col-6
span(id='previousLink') #{products.pageInfo.prevPageUrl ? products.pageInfo.prevPageUrl : '' }
button.btn.btn-outline-dark.ml-4(id="previous_btn")
i(class="bi bi-arrow-left-circle-fill") Précédent
div.col-6
span(id='nextLink') #{products.pageInfo.nextPageUrl ? products.pageInfo.nextPageUrl : '' }
a.btn.btn-outline-dark.float-right.mr-4(id="next_btn") Suivant
i(class="fa-solid fa-circle-arrow-right")
window.addEventListener('DOMContentLoaded', () => {
console.log('dom content loaded')
document.getElementById('next_btn').onclick = function (e) {
console.log('next button clicked')
const nextLink = document.getElementById('nextLink').innerHTML;
fetch(nextLink).then(response => {
console.log(response);
}).catch(error => {
console.log(error)
})
console.log(nextLink)
}
});
You're doing it wrong. If you want to display Shopify products in your own App, you use the StorefrontAPI calls. With a StorefrontAPI token, you get products, and can display them. Trying to use Admin API calls is never going to work properly. Switch to StorefrontAPI and all your problems go away.

not able to send request to express server using axios

I am building a chat application like whatsapp, & implementing the feature - when user clicks on any person's name, his chats appears, but can't able to send request to server when user clicks
Source code
There is div, when user will click on it, it will fetch data from server (onclick event handler) in Sidebar.js file -
{friends.map((e) => (
<div
onClick={getChatDetails}
key={e.friendName}
className='sidebar_chat_info'>
<Avatar />
<div>
<h2>{e.friendName}</h2>
<p>{getLastMessage()}</p>
</div>
</div>
))}
this is getChatDetails function in sidebar.js file
const getChatDetails = (e) => {
//console.log(e.target.textContent);
const Myfriend = e.target.textContent;
axios
.post('http://localhost:2000/message/get', { friend: Myfriend })
.then((response) => {
console.log(response);
})
.catch((error) => console.log(error));
};
At the server side , this is route in index.js file
Server is running on port 2000
app.post('/message/get', isloggedIn, async (req, res) => {
console.log('REQUESTED!');
try {
const conversation = await req.user.MyConversation.find(
(element) => element.friendName == req.body.friend
);
const messages = await conversationModel.findById(conversation.chats);
res.send(messages);
//await MessageModel.remove({})
} catch (error) {
res.status(500).send(error);
}
});
This is error on browser console , when I am clicking on div
But when I am sending request through postman, I am getting response
When I am sending request in other files (login.js), it's working there, don't know why it is not working only Sidebar.js file
The issue that you're having is that e in getChatDetails is undefined. The reason for this is is onclick does not pass an event object. In order to pass an event object to your sidebar function, you need to attach an event listener to it, which is a bit better than using onclick in most cases anyways (imo). Something like this:
const sidebar = document.getElementsByClassName('sidebar_chat_info')
for (let i = 0; i < sidebar.length; i++) {
sidebar[i].addEventListener('click', handleClick = e => {
//console.log(e.target.textContent);
const Myfriend = e.target.textContent;
axios
.post('http://localhost:2000/message/get', { friend: Myfriend })
.then((response) => {
console.log(response);
})
.catch((error) => console.log(error));
})
The middleware "isLoggedIn" causing issue. The problem was in my authentication part, when the user has been logged in then only he will see home page
index.js file at line 113
I added console.log and found that "NOT LOGGED IN " is displayed
function isloggedIn(req, res, next) {
if (req.isAuthenticated()) {
return next();
} else {
console.log('NOT LOGGED IN !');
res.status(500).send('DENIED PERMISSION!');
}
}
I think it is happening because after logging in , I am redirecting to home page from
Login.js at line 59
history.push('/', { user: response.data });
const submitForm = async (e) => {
e.preventDefault();
axios
.post('http://localhost:2000/login', {
username: username,
password: password,
})
.then((response) => {
history.push('/', { user: response.data });
})
.catch((error) => setIsError(true));
//console.log(user.data); //user.data contains the details
//CALLING THE HOME PAGE AFTER SIGNUP & SENDING DETAILS OF CURRENT USER THERE !
//history.push('/', { user: user.data });
};
Maybe the request will be authenticated only from Login.js file, but I can't make other request from this file like getting chats details, sending message etc. I will have to go to home page . That's why I am redirecting to home page after logging in
On home page my request is not authenticated.
In postman all routes are working as I am not switching pages.
Login and logout routes are working as they are not taking in account "isLoggedIn"
Please suggest how to work with routes that needs authentication, like send message, gettingchats details?
PS - My request is even not authenticated from Login.js. After logging in, this time I didn't redirect to home page. I made request to route that needs authentication after logging in , it's still showing "NOT LOGGED IN" on server

Using firebase authentication and firestore to add user

Im trying to use user to the authentication of firebase and also firestore. Whhen I click on Save, the function SavePress is activated. The first time I click on this button, the user is added to firebase authentication but user is equal to null. Only at the second time it's work.
If anyone can help me..
Here is my code :
SavePress=async()=>{
if(this.state.email==="" || this.state.password==="" || this.state.firstname==="" || this.state.lastname==="" || this.state.confirmpassword==="" || (this.state.status===""))
{
alert("All fields are required")
}
else{
await firebase.auth().createUserWithEmailAndPassword(email,password)
.then(
firebase.auth().onAuthStateChanged(user=>
{
console.log("user : ",user)
if(user!=null)
{
firebase.firestore().collection("Users").doc(firebase.auth().currentUser.uid)
.set({firstname,lastname,email,status})
.then(this.checkStatus(status,{user}))
}
})
)
.catch((error)=>
{
console.log(error.code);//revoir cette erreur
if(error.code == "auth/email-already-in-use")
{alert("User already exists. Try to log in")}
})
}
}
Alternatively to Aymen's answer, you actually don't need an onAuthStateChanged in your then() callback. Since the then() callback is called when the user has been successfully created, you can simply do:
firebase.auth().createUserWithEmailAndPassword(email,password).then((credentials) => {
const user = credentials.user;
firebase.firestore().collection("Users").doc(firebase.auth().currentUser.uid)
.set({firstname,lastname,email,status})
.then(this.checkStatus(status,{user}))
).catch((error)=>{
console.log(error.code);//revoir cette erreur
if(error.code == "auth/email-already-in-use")
{alert("User already exists. Try to log in")}
})
when you sign to firebase, firebase auth take time to change auth, for this reason, you got a null in the first press. you need to use a listener for auth change.
firebase.auth().onAuthStateChanged(user => {
if(user){
// add user to firestore database.
}
})

Firebase Auth: managing users with the Admin SDK

I have to write a firebase function that receives a JSON with a list of users and has to manage them with the following rules. For each user in the received list:
If the user is already registered (email/password) in firebase, I update it.
If the user is not registered yet, I create it
If a user is registered in firebase but it's not present in the received list, I disable it.
Now, I came up with the following solution: I iterate for each user in the received list. I call admin.auth().createUser() method so that if the user is not registered it will be created, otherwise the method throws an error and in the catch() block I call admin.auth().updateUser().
For the second part, I retrieve all the users registered with admin.auth().listUsers() and for each of them I check whether it's present in the received list: if don't so, I disable it.
For some reason, the correctness of this solution is uncertain: sometimes it doesn't work at all, other times when I call the function once it doesn't work but the second time a call the function it works, idk why is that.
This only happens when I send to the function a lot of users (about 400). If I send only few users it works fine.
Could anyone suggest to me maybe a better solution? Thanks a lot for your answer.
This is the function:
exports.addClients = functions.https.onRequest(async (req, res) => {
// fetch recevied list from payload
var receivedClients = req.body.clients;
// create or update user
receivedClients.forEach(client => {
admin.auth().createUser({
uid: client.id,
email: client.email,
emailVerified: true,
password: client.password,
})
.catch(err => {
// update user
admin.auth().updateUser(client.id, {
email: client.email
}).catch(err => {
// error updating user
log("Error updating user: " + err);
});
})
});
// disabling users not present in the received list
listUsers = await admin.auth().listUsers();
userRecords = listUsers.users;
userRecords.forEach(record => {
if (!receivedClients.some(client => client.id === record.uid)) {
// disable user
admin.auth().updateUser(record.uid, {
disabled: true
})
.catch(err => {
// error disabling user
log("Error disaling user: " + err);
});
}
});
// send response
res.sendStatus(200);
});

Increment field user.entries when I hit submit

any idea how to increment a field called 'entries' by 1 every time I hit the submit button and save it to the database (I am using MongoDB/mongoose)?
app.put('/image', (req, res) => {
const { id } = req.body;
User.findByIdAndUpdate(id)
.then(user => {
return res.json(user.entries);
})
.catch(err => {
res.status(400).json('Error getting entries');
console.log(err);
})
});
I tried the auto-incremet plugin, but I don't know if it works in this case, if so I couldn't quite place it in the right place. I also tried to add like
User.findByIdAndUpdate(id, {$inc: {'entries': 1}} but it only starts to work when I hit the but twice and on.
If anyone can help me It'd be a great help!! Thanks
It is working. The only reason is that, findByIdAndUpdate returns the document before actually performing the update operation. If you want to get the increment value after the update operation, You might want to split the findByIdAndUpdate and try
User.update({_id: id},{$inc: {'entries': 1}}).then(() => {
User.findOne({_id: id}).then( user =>{
return res.json(user.entries);
})
}).catch(err => {
res.status(400).json('Error getting entries');
console.log(err);
})
You could also check this solution out by #Jonathan Lonowski if you still want to go with the findByIdAndUpdate.

Categories

Resources