I would like to explain my problem of the day.
currently, I post a message in my database, then in the same component I perform a get to display the data sent just before.
my problem and the next one I have to update the page manually to display my get,
I would like to find a solution to directly display the result without having to press F5
How can I fix this issue?thx all
make room for the code :)
post
postBack(e,) {
e.preventDefault();
const payload = {
phone: this.state.phone,
total: this.state.total ,
}
axios.post('******', payload)
.then(res => {
if (res.error) {
alert(res.error);
}
}).catch(e => {
console.error(e);
}).finally(() => this.setState({
redirect: true
}));
}
get
getRandom = async () => {
const res = await axios.get(
'*****'
)
this.setState({ data: res.data })
}
componentDidMount() {
this.getRandom()
}
render
render() {
let datas = this.state.data.map(chat => {
return (
<form onSubmit={(e) => this.handleSubmit(e, chat,)}>
<label>
<input type="text" name="name" onChange={this.handleChange} />
</label>
<button type="submit">Envoyer</button>
</form>
<div key={chat.id}>
<div key={chat.id}>
<p> your name is {chat.name} </p>
</div>
</div>
)
})
return (
<div>
{datas}
</div>
)
}
}
You can update data state after POST request is success.
The code seems incomplete but it would be something like this
postBack(e,) {
e.preventDefault();
const payload = {
phone: this.state.phone,
total: this.state.total ,
}
axios.post('******', payload)
.then(res => {
if (res.error) {
alert(res.error);
} else { // here should be place to update state
this.setState({ data: payload })
}
}).catch(e => {
console.error(e);
}).finally(() => this.setState({
redirect: true
}));
}
Related
Sign In button, when I click it, it connects to Azure, you log in and it returns the email of the person who logged in. The goal is to update the "permission" status, I already did console.log but it doesn't update but it prints the user type "admin".
function handleLogin(instance) {
instance.loginPopup(loginRequest).catch(e => {
console.error(e);
});
}
/*Renders a button which, when selected, will open a popup for login*/
export const SignInButton = ({name, nameChange, user}) => {
const url = "http://localhost:5000/flask/verify";
const [permission, setPermision] = useState({val : "null"});
useEffect(() => {
Axios.post(url, {
correo : user,
})
.then((res)=>{
console.log("response: ", res.data);
setPermision({val : res.data});
})
.catch((error) => {
console.log(error);
});
}, [user])
const { instance } = useMsal();
console.log('permission:', permission);
return (
<button className="btn" type="button" onClick={() => {handleLogin(instance);}}>SignIn</button>
);
}
information from the console
I have a component like this -->
<form onSubmit={verifyOTP}>
....
.....
<div className="auth-btn-wrap">
<button disabled={isLoading ? true : false} type="submit" className="btn btrimary">
{isLoading ? (<CircularProgress />) : (<>Verify OTP</>)}</button>
{isLoading ? null : (<Link onClick={resendOTP}>Resend</Link>)}
</div>
<div id="recaptcha-container" />
</form>
verifyOTP function looks like this -->
const verifyOTP = (e: React.SyntheticEvent) => {
e.preventDefault();
if (window.confirmationResult) {
window.confirmationResult
.confirm(otp)
.then(async () => {
dispatch(signupStartStart({ user: { ...user, otp, otpConfirm: window.confirmationResult }, history }));
})
.catch((e: any) => {
console.error(e);
snack.error("Invalid OTP");
});
} else {
window.location.reload();
}
};
In my user saga file, action signupStartStart looks like this -->
{.......
.......
const result = yield call(sendOTPWithFb, {
phoneNumber: user.countryCode + user.phoneNumber, containerName: "recaptcha-container"
});
yield put (setLoading ({loading: false}));
if (result) {
yield put(showVerifyOTPSuccess());
snack.success('An OTP has been sent to you mobile');
} else {
snack.error("Unable to send OTP");
}
}
The function that sends OTP is this -->
export const sendOTPWithFb = async (data: any): Promise<boolean> => {
const { phoneNumber, containerName } = data
try {
const appVerifier = new FirebaseTypes.auth.RecaptchaVerifier(
containerName,
{
size: "invisible",
}
);
const confirmationResult = await firebase
.auth()
.signInWithPhoneNumber(`${phoneNumber}`, appVerifier);
window.confirmationResult = confirmationResult;
return true;
} catch (error) {
console.error(error);
return false;
}
};
Whenever I click on Resend OTP button, it gives me error that --->
"reCAPTCHA has already been rendered in this element"
PLease let me know how to resolve this issue
I'm fetching some data from firestore and everything works, but there is one big flaw I'm trying to figure out…
I can only console log the data once I press on the “Read Data” button twice. Any help on how I can make it wait for it to have the response before showing it?
Bellow is my code, thanks in advance.
import firebase from 'firebase/compat/app'
import 'firebase/compat/firestore';
import { useState } from 'react';
export default function ReadToFirebase() {
const [data, setData] = useState([])
const readData = () => {
try {
firebase
.firestore()
.collection('users')
.onSnapshot(snapshot => {
let changes = snapshot.docChanges()
changes.forEach(change => {
let data = change.doc.data()
data = {
username: data.userName,
email: data.email
}
setData(oldArray => [...oldArray, data])
})
})
console.log('Data Read!')
console.log(data);
// return data
} catch (error) {
console.log(`Opps! Error querying data: \n\n ${error}`);
alert(error)
}
}
return (
<div className="p-4 grid place-items-center space-y-2">
<button onClick={readData} className="py-2 px-4 bg-gray-300 rounded-xl font-bold">Read Data</button>
<div className="">{}</div>
</div>
)
}
Your console.log statement is outside the onSnapshot function.
If you do something like this:
const readData = () => {
try {
firebase
.firestore()
.collection('users')
.onSnapshot(snapshot => {
let changes = snapshot.docChanges()
changes.forEach(change => {
let data = change.doc.data()
data = {
username: data.userName,
email: data.email
}
setData(oldArray => [...oldArray, data])
});
console.log('Data Read!')
console.log(data);
})
// return data
} catch (error) {
console.log(`Opps! Error querying data: \n\n ${error}`);
alert(error)
}
}
It'll work.
Two things to note here:
You can improve your code by using map instead of forEach:
const changedData = changes.map(change => {
let data = change.doc.data()
return {
username: data.userName,
email: data.email
}
});
setData(oldArray => [...oldArray, ...changedData])
In order for the try/catch to actually catch server error you should wrap your request in a promise. Something like:
const readData = () => {
new Promise((resolve, reject) => {
firebase.firestore().collection('users').onSnapshot(handleSnapshot(resolve, reject)());
})
.then(handleSuccessfulUsersFetch)
.catch(handleErrorInUsersFetch);
}
There are other ways you could achieve that (for instance with async/await). You can read more about error handling in JS in this nice article:
https://medium.com/walkme-engineering/javascript-error-handling-9fc1a2946119
I have this friends component where I search the database for the user's friends (stored in a string separated by commas) and display them in a scrollable div. You can also add a new friend. Everything is working fine in the database and the backend. However, the component isn't being re-rendered when the state changes. It's dependent on 'allFriends' so it should re-render when that gets updated. Do you guys have any idea what's going on here? I'm guessing it has something to do with asynchronicity but I can't seem to pinpoint it. I added a comment for each code block to try to make it a little easier to read.
import React, { useState, useEffect } from 'react';
import SingleFriend from './SingleFriend';
import './friends.css';
const Friends = ({username}) => {
const [allFriends, setAllFriends] = useState([]);
const [unsortedFriends, setUnsortedFriends] = useState([]);
const [friendFilter, setFriendFilter] = useState('');
const [friendSearch, setFriendSearch] = useState('');
//-----------------------------------------------------------------------------------
// Start fetching friends on component mount
//-----------------------------------------------------------------------------------
useEffect(() => {
fetchFriends();
}, [])
//-----------------------------------------------------------------------------------
// Sort the friends when fetching has finished/unsortedFriends has updated
//-----------------------------------------------------------------------------------
useEffect(() => {
const onlineFriends = [];
const offlineFriends = [];
unsortedFriends.forEach(f => {
if (f.status === 'online') {
onlineFriends.push(f)
} else {
offlineFriends.push(f)
}
})
setAllFriends(onlineFriends.concat(offlineFriends));
},[unsortedFriends])
//-----------------------------------------------------------------------------------
// Get the string of friends that is stored in the database for the user
// Convert to array of friends
// Pass the array to 'fetchFriendData()'
//-----------------------------------------------------------------------------------
const fetchFriends = () => {
let allFriendNames = [];
fetch(`http://localhost:8000/getFriends?username=${username}`)
.then(res => res.json())
.then(friends => {
if (friends !== null && friends !== '') {
allFriendNames = friends.split(',');
fetchFriendData(allFriendNames);
}
})
}
//-----------------------------------------------------------------------------------
// Search the database for each of the user's friends
// Return those users, and add their username & online status to a temporary array
// Assign that array to the unsortedFriends useState hook
//-----------------------------------------------------------------------------------
const fetchFriendData = (allFriendNames) => {
let allF = [];
for (let friend of allFriendNames) {
fetch(`http://localhost:8000/findFriend?username=${friend}`)
.then(res => res.json())
.then(user => {
if (user.socketid) {
allF.push({name: user.username, status: 'online'})
} else {
allF.push({name: user.username, status: 'offline'})
}
})
.catch(err => console.log(err))
}
document.querySelector('.addFriendInput').value = '';
setUnsortedFriends(allF);
}
//-----------------------------------------------------------------------------------
// Called on button press to add friend
//-----------------------------------------------------------------------------------
const addFriend = () => {
let friendList = '';
let friendArray = [];
//-----------------------------------------------------------------------------------
// Search the database to check if the name that was
// entered matches any users in the databse
//-----------------------------------------------------------------------------------
fetch(`http://localhost:8000/findFriend?username=${friendSearch}`)
.then(res => res.json())
.then(user => {
if (user.username) {
//-----------------------------------------------------------------------------------
// If friend exists, grab the user's friend list string
// Make a temporary string and array with the new friend
//-----------------------------------------------------------------------------------
fetch(`http://localhost:8000/getFriends?username=${username}`)
.then(res => res.json())
.then(friends => {
if (friends !== null && friends !== '') {
friendArray = friends.split(',');
if (friendArray.includes(friendSearch)) {
throw new Error('Problem getting friend')
} else {
friendArray.push(friendSearch);
friendList = friends.concat(`,${friendSearch}`);
}
} else {
friendList = friendSearch;
friendArray = [friends];
}
//-----------------------------------------------------------------------------------
// Update the user's friend list with the new friends string
// Pass the updated friends array to 'fetchFriendData'
//-----------------------------------------------------------------------------------
fetch('http://localhost:8000/addFriend', {
method: 'put',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
username: username,
friendlist: friendList
})
})
.then(fetchFriendData(friendArray))
.catch(err => console.log(err))
})
.catch(err => console.log(err))
}
})
.catch(err => console.log(err))
}
return (
<div className='friendsContainer'>
<div className='friendsSection'>
<h2>Friends</h2>
<input onChange={(e) => setFriendFilter(e.target.value)} type='text' placeholder='Enter a username'/>
<div className='friendsListContainer'>
{
allFriends.length
?
<div className='friendsList'>
{
//-----------------------------------------------------------------------------------
// Map through the user's friends
// Return a single friend div w/ their username and status
//-----------------------------------------------------------------------------------
allFriends.map(f => {
if (f.name.toLowerCase().includes(friendFilter.toLowerCase())) {
return <SingleFriend key={f.name} name={f.name} status={f.status}/>
} else return null
})
}
</div>
: <h4 className='noFriends'>No friends have been added</h4>
}
</div>
<div className='addFriend'>
<h3 className='addFriendText' >Add a friend</h3>
<input className='addFriendInput' onChange={(e) => setFriendSearch(e.target.value)} type='text' placeholder='Enter a username'/>
<button onClick={addFriend} >Add</button>
</div>
</div>
</div>
)
}
export default Friends;
you need wait fetch response data
const fetchFriendData = async (allFriendNames) => {
let allF = [];
for (let friend of allFriendNames) {
const response = await fetch(`http://localhost:8000/findFriend?username=${friend}`)
const user = await response.json()
if (user.socketid) {
allF.push({name: user.username, status: 'online'})
} else {
allF.push({name: user.username, status: 'offline'})
}
}
document.querySelector('.addFriendInput').value = '';
setUnsortedFriends(allF);
}
class App extends React.Component {
constructor(props) {
super(props);
this.addCriminalData = this.addCriminalData.bind(this);
this.storeDocumentAndgetUrl = this.storeDocumentAndgetUrl.bind(this);
this.storeForensicDocumentAndgetUrl = this.storeForensicDocumentAndgetUrl.bind(
this
);
this.state = {
username: "",
imgFile: [],
imgUrl: [],
docFile: [],
docUrl: [],
docForensicFile: [],
docForensicUrl: [],
};
}
upload = (e) => {
e.preventDefault();
this.storeForensicDocumentAndgetUrl(this.storeDocumentAndgetUrl);
};
storeImageAndgetUrl = (addCriminalData) => {
const storage = fire.storage();
const reference = storage.ref();
this.state.imgFile.forEach((file) => {
reference
.child(file.name)
.put(file)
.then(
(snapShot) => {
snapShot.ref.getDownloadURL().then((url) => {
this.setState(
(prevState) => ({
imgUrl: [...prevState.imgUrl, url],
}),
() => addCriminalData()
);
});
},
(err) => {
console.log(err);
}
);
});
};
storeDocumentAndgetUrl = (storeImageAndgetUrl) => {
const storage = fire.storage();
const reference = storage.ref();
this.state.docFile.forEach((file) => {
reference
.child(file.name)
.put(file)
.then(
(snapShot) => {
snapShot.ref.getDownloadURL().then((url) => {
this.setState(
(prevState) => ({
docUrl: [...prevState.docUrl, url],
}),
() => storeImageAndgetUrl(this.addCriminalData)
);
});
},
(err) => {
console.log(err);
}
);
});
};
storeForensicDocumentAndgetUrl = (storeDocumentAndgetUrl) => {
const storage = fire.storage();
const reference = storage.ref();
let refer = [];
this.state.docForensicFile.forEach((file) => {
reference
.child(file.name)
.put(file)
.then(
(snapShot) => {
snapShot.ref.getDownloadURL().then((url) => {
refer.push(url);
});
this.setState({ docForensicUrl: refer }, () => {
storeDocumentAndgetUrl(this.storeImageAndgetUrl);
});
},
(err) => {
console.log(err);
}
);
});
};
setImage = (e) => {
if (Array.from(e.target.files).length <= 4) {
const img = Array.from(e.target.files);
this.setState({ imgFile: img });
} else {
alert("You can select maximum 5 Images");
}
};
setDocument = (e) => {
if (Array.from(e.target.files).length <= 4) {
const doc = Array.from(e.target.files);
this.setState({ docFile: doc });
} else {
alert("You can select maximum 5 Documents");
}
};
setForensicDocument = (e) => {
if (Array.from(e.target.files).length <= 4) {
const doc = Array.from(e.target.files);
this.setState({ docForensicFile: doc });
} else {
alert("You can select maximum 5 Documents");
}
};
addCriminalData = () => {
console.log(this.state.pic);
const db = fire.firestore();
let sgn = this.state.selectedGangName;
console.log(sgn);
const userRef = db.collection("students").add({
name: this.state.username,
pic: this.state.imgUrl,
docUrl: this.state.docUrl,
docForensicUrl: this.state.docForensicUrl,
});
};
handleChangeUsername = (e) => {
this.setState({ [e.target.name]: e.target.value });
};
render() {
return (
<div className="App">
<form onSubmit={this.upload}>
<label>Username:</label>
<input
type="text"
value={this.state.username}
name="username"
onChange={this.handleChangeUsername}
/>
<input
type="file"
accept="image/*"
onChange={this.setImage}
multiple
/>
<input
type="file"
onChange={this.setDocument}
label="Upload Accused mobile details in file/PDF format "
accept="image/*,application/pdf"
onKeyPress={(e) => {
e.key === "Enter" && e.preventDefault();
}}
multiple
/>
<input
type="file"
onChange={this.setForensicDocument}
label="Upload Accused mobile details in file/PDF format "
accept="image/*,application/pdf"
onKeyPress={(e) => {
e.key === "Enter" && e.preventDefault();
}}
multiple
/>
<button type="submit">Submit</button>
</form>
</div>
);
}
}
Here, In the above code, I have one text input box and two file input boxes and all of those fields are multiples. And i have made call back functions such that first documents and images will upload and get URL, and then that URL along with text input will be stored to firestore. On click of submit button it goes to upload function, then from there it goes to 'storeForensicDocumentAndgetUrl' method, and then 'storeDocumentAndGetUrl' method and then 'storeImageAndGetUrl' method and after getting all URLs it will call 'addCriminalData' method. The callback functions are working correctly, but its storing multiple documents for one time with not proper URL array length with respect to files i have provided.