How To Refresh User data coming from a variable route? I have a variable called "user" which is coming from a different screen by "react navigation" route that user variable contains all the data I need, So How can I reload that user variable data after "Set follow" is true without fetching anything because "user" variable data is coming is fetching from a different screen?
Code:
const Profile = ({ navigation, route }) => {
const { user } = route.params; // HERE IS THAT USER VAR
const [issameuser, setIssameuser] = useState(false)
const [follow, SetFollow] = useState(false)
const isMyProfile = async (otherprofile) => {
AsyncStorage.getItem('user').then((loggeduser) => {
const loggeduserobj = JSON.parse(loggeduser)
if (loggeduserobj.user.username == otherprofile[0].username) {
setIssameuser(true)
}
else {
setIssameuser(false)
}
})
}
const CheckFollow = async (otherprofile) => {
AsyncStorage.getItem('user')
.then(loggeduser => {
const loggeduserobj = JSON.parse(loggeduser);
return fetch('http://10.0.2.2:3000/checkfollow', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
followfrom: loggeduserobj.user.username, followto: otherprofile[0].username
})
})
})
.then(res => res.json())
.then(data => {
if (data.message == "User in following list") {
SetFollow(true)
} else if (data.message == "User not in following list") {
SetFollow(false)
} else {
alert('Please Try Again!')
}
})
}
const FollowUser = async (otherprofile) => {
const loggeduser = await AsyncStorage.getItem('user')
const loggeduserobj = JSON.parse(loggeduser)
fetch('http://10.0.2.2:3000/Follow', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
followfrom: loggeduserobj.user.username, followto: otherprofile[0].username
})
})
.then(res => res.json())
.then(data => {
if (data.message == "User Followed") {
SetFollow(true) // HERE I WANT TO RE-LOAD USER VAR DATA
}
else {
alert("Pleas Try Again")
}
})
}
useEffect(() => {
isMyProfile(user)
CheckFollow(user)
},)
}
is their any method to do that or i need to use socketio?
Related
How are messages sent slowly? I am using socket.io for sending messages but my app sending messages is working very slowly it almost takes 8-10 seconds on average to send messages how can I improve its performance? I tried using use callback but still is not sending messages fast what can i do to improve its performance?
const { otheruser } = route.params;
const [mydata, setMyData] = useState(null);
const [userid, setUserid] = useState(null);
const [roomid, setRoomid] = useState(null);
const [chat, setChat] = useState(['']);
const [currentmessage, setCurrentmessage] = useState(null);
useEffect(() => {
LoadData()
}, [])
useEffect(() => {
socket.on('receive_message', (data) => {
LoadMessages(roomid)
})
}, [socket])
const SortRoomId = (id1, id2) => {
if (id1 > id2) {
return id1 + id2
} else {
return id2 + id1
}
}
const LoadData = async () => {
try {
const value = await AsyncStorage.getItem('user');
const { token, user: { email } } = JSON.parse(value);
const res = await fetch('http://10.0.2.2:3000/userdata', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer' + token
},
body: JSON.stringify({ email })
});
const { message, user } = await res.json();
if (message === 'User Found') {
setMyData(user);
setUserid(user._id);
const ChatRoomId = await SortRoomId(otheruser[0]._id, user._id);
setRoomid(ChatRoomId);
socket.emit('joinroom', { roomid: ChatRoomId });
LoadMessages(ChatRoomId);
} else {
alert('Login Again');
navigation.navigate('Login');
}
} catch (err) {
navigation.navigate('Login');
}
};
const SendMessage = useCallback(async () => {
const MessageData = {
message: currentmessage,
RoomId: roomid,
SenderId: userid,
RecieverId: otheruser[0]._id
};
try {
const response = await fetch('http://10.0.2.2:3000/SaveMessage', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(MessageData)
});
const data = await response.json();
if (data.message === 'Message saved') {
socket.emit('sendmessage', MessageData);
LoadMessages(roomid);
console.log('message sent');
setCurrentmessage('');
} else {
alert('Network Error');
setCurrentmessage('');
}
} catch (error) {
console.error(error);
}
}, [currentmessage, roomid, userid, otheruser, socket]);
useEffect(() => {
LoadMessages(roomid)
}, [chat])
const LoadMessages = async (ChatRoomId) => {
try {
const res = await fetch('http://10.0.2.2:3000/GetMessages', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ RoomId: ChatRoomId })
});
const data = await res.json();
setChat(data);
} catch (error) {
console.error(error);
}
}
WARN Possible Unhandled Promise Rejection (id: 21): TypeError: undefined is not an object (evaluating 'res.json') How can I fix this problem in my code? I tried logging user and loggeduserobj both logs correctly but still, this error is coming I also logged the type of loggeduserobj it logs object Can you help me to fix this problem?
const { user } = route.params;
const [issameuser, setIssameuser] = useState(false)
const [follow, SetFollow] = useState(false)
const isMyProfile = async (otherprofile) => {
AsyncStorage.getItem('user').then((loggeduser) => {
const loggeduserobj = JSON.parse(loggeduser)
if (loggeduserobj.user.username == otherprofile[0].username) {
setIssameuser(true)
}
else {
setIssameuser(false)
}
})
}
const CheckFollow = async (otherprofile) => {
AsyncStorage.getItem('user')
.then(loggeduser => {
const loggeduserobj = JSON.parse(loggeduser);
fetch('http://10.0.2.2:3000/checkfollow', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
followfrom : loggeduserobj.user.username, followto: otherprofile[0].username
})
})
})
.then(res => res.json())
.then(data => {
if (data.message == "User in following list") {
SetFollow(true)
}
else if (data.message == "User not in following list") {
SetFollow(false)
}
else {
alert('Please Try Again!')
}
})
}
useEffect(() => {
isMyProfile(user)
CheckFollow(user)
}, [])
Backend:
router.post('/checkfollow', (req, res) => {
const { followfrom, followto } = req.body;
console.log(followfrom, followto);
if (!followfrom || !followto) {
return res.status(422).json({ error: "Invalid Credentials" });
}
User.findOne({ username: followfrom })
.then(mainuser => {
if (!mainuser) {
return res.status(422).json({ error: "Invalid Credentials" });
}
else {
let data = mainuser.following.includes(followto);
console.log(data);
if (data == true) {
res.status(200).send({
message: "User in following list"
})
}
else {
res.status(200).send({
message: "User not in following list"
})
}
}
})
.catch(err => {
return res.status(422).json({ error: "Server Error" });
})
})
You need to return a Promise, the result of fetch, from your first .then() so that it can be chained on, like so:
const CheckFollow = async (otherprofile) => {
AsyncStorage.getItem('user')
.then(loggeduser => {
const loggeduserobj = JSON.parse(loggeduser);
return fetch('http://10.0.2.2:3000/checkfollow', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
followfrom : loggeduserobj.user.username, followto: otherprofile[0].username
})
})
})
.then(res => res.json())
.then(data => {
if (data.message == "User in following list") {
SetFollow(true)
} else if (data.message == "User not in following list") {
SetFollow(false)
} else {
alert('Please Try Again!')
}
})
}
You should also consider using await in this case, especially since your function is already marked as async to make things more readable
const CheckFollow = async (otherprofile) => {
const loggeduser = await AsyncStorage.getItem('user');
const loggeduserobj = JSON.parse(loggeduser);
const res = await fetch('http://10.0.2.2:3000/checkfollow', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
followfrom : loggeduserobj.user.username, followto: otherprofile[0].username
})
});
const data = await res.json();
if (data.message == "User in following list") {
SetFollow(true)
} else if (data.message == "User not in following list") {
SetFollow(false)
} else {
alert('Please Try Again!')
}
}
whenever I click the delete button its works fine but I don't get the output like " deleted successfully " its shows .then undefined..
const deleteThisCategory = (CategoryId) => {
deleteCategory(CategoryId, user._id, token).then(data => {
if (data.error) {
console.log(data.error);
} else {
preload();
}
});
};
here is the delete category API call
export const deleteCategory = (userId, categoryId , token) => {
fetch(`${API}/category/${categoryId}/${userId}`, {
method: "DELETE",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type":"application/json"
},
})
.then(response => {
return response.json();
})
.catch(err => console.log(err));
};
It should be like this. deleteCategory needs to send only promise. Later where ever you are resolving you have to use then.
export const deleteCategory = (userId, categoryId , token) => {
return fetch(`${API}/category/${categoryId}/${userId}`, {
method: "DELETE",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type":"application/json"
}
})
};
const deleteThisCategory = (CategoryId) => {
deleteCategory(CategoryId, user._id, token).then(data => {
preload();
}).catch(err => {
console.log(err);
})
};
I would like to explain my problem of the day.
in the following code I map a table, and I post all of this in a database
everything works fine. the only problem and the format in which I receive it.
{
"id": 136,
"items": "[{\"title\":\"Campus (Pinte)\",\"quantity\":2}]",
}
I would rather recover it in another format than in arrays. here is my code:
postbackend = () => {
const newItems = this.props.items.map(item => {
const { title, quantity } = item;
return {
title,
quantity
};
});
const config = {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({ ...this.state, items: newItems })
};
const url = entrypoint + "/alluserpls";
fetch(url, config)
.then(res => res.json())
.then(res => {
if (res.error) {
alert(res.error);
this.props.history.replace("/OrderSummaryPaymentFalseScreen"); // Your Error Page
} else {
alert(`film ajouté avec l'ID ${res}!`);
this.props.history.push("/OderSummaryScreen"); // Your Success Page
}
})
.catch(e => {
console.error(e);
this.props.history.replace("/OrderSummaryPaymentFalseScreen"); // Your Error Page
})
.finally(() =>
this.setState({
redirect: true
})
);
};
Do you have an idea of how to fix this?
I am a noob, using vue.js and a node auth api, the api works fine and provides the jwt token in the response, my question is how can i use the token in all the requests that follows (using axios), and any best practices for handling the token in the front end is also appreciated.
Thanks
You can use something like that for Your scenario in your vuejs app.
import axios from 'axios'
const API_URL = 'http://localhost:3000'
const securedAxiosInstance = axios.create({
baseURL: API_URL,
withCredentials: true,
headers: {
'Content-Type': 'application/json'
}
})
const plainAxiosInstance = axios.create({
baseURL: API_URL,
withCredentials: true,
headers: {
'Content-Type': 'application/json'
}
})
securedAxiosInstance.interceptors.request.use(config => {
const method = config.method.toUpperCase()
if (method !== 'OPTIONS' && method !== 'GET') {
config.headers = {
...config.headers,
'X-CSRF-TOKEN': localStorage.csrf
}
}
return config
})
securedAxiosInstance.interceptors.response.use(null, error => {
if (
error.response &&
error.response.config &&
error.response.status === 401
) {
return plainAxiosInstance
.post('/refresh', {}, { headers: { 'X-CSRF-TOKEN': localStorage.csrf } })
.then(response => {
localStorage.csrf = response.data.csrf
localStorage.signedIn = true
let retryConfig = error.response.config
retryConfig.headers['X-CSRF-TOKEN'] = localStorage.csrf
return plainAxiosInstance.request(retryConfig)
})
.catch(error => {
delete localStorage.csrf
delete localStorage.signedIn
location.replace('/')
return Promise.reject(error)
})
} else {
return Promise.reject(error)
}
})
export { securedAxiosInstance, plainAxiosInstance }
And in your component you use this to process your request with api
Products.vue
export default {
name: 'products',
data () {
return {
products: [],
newProduct: [],
error: '',
editedProduct: ''
}
},
created () {
if (!localStorage.signedIn) {
this.$router.replace('/')
} else {
this.$http.secured.get('/api/v1/products')
.then(response => { this.products = response.data })
.catch(error => this.setError(error, 'Something went wrong'))
}
},
methods: {
setError (error, text) {
this.error = (error.response && error.response.data && error.response.data.error) || text
},
addProduct () {
const value = this.newProduct
if (!value) {
return
}
this.$http.secured.post('/api/v1/products/', { product: { name: this.newProduct.name } })
.then(response => {
this.products.push(response.data)
this.newProduct = ''
})
.catch(error => this.setError(error, 'Cannot create product'))
},
removeProduct (product) {
this.$http.secured.delete(`/api/v1/products/${product.id}`)
.then(response => {
this.products.splice(this.products.indexOf(product), 1)
})
.catch(error => this.setError(error, 'Cannot delete product'))
},
editProduct (product) {
this.editedproduct = product
},
updateProduct (product) {
this.editedProduct = ''
this.$http.secured.patch(`/api/v1/products/${product.id}`, { product: { title: product.name } })
.catch(error => this.setError(error, 'Cannot update product'))
}
}
}
You can find here a lot of good patterns which I personally use on my projects and how also JWT token handling.
For saving token in a brower, you can use cookie, sessionStorage or localStorate, last one is the most popular now (short explination here).
In a few words, you can create an axion instance and add a token before request sent.
const http = axios.create({
baseURL: process.env.VUE_APP_SERVER_API,
// here you can specify other params
})
http.interceptors.request.use(request => {
// Do something before request is sent
request.headers['Authorization'] = `JWT ${TOKEN_HERE}`
// some logic what to do if toke invalid, etc ...
return request
}, function (error) {
// Do something with request error
return Promise.reject(error)
})