Navigation failed after logging in with react-native-fbsdk - reactjs

I am using the FBSDK to do the registration in react native. I need the name, last name and email in order to pass it to the registration screen and fill the mentioned fields there automatically. Here is my code in login screen:
async _fbAuth() {
//console.log("that", that);
let { isCancelled } = await LoginManager.logInWithReadPermissions(['public_profile','user_posts', 'email','user_birthday']);
if ( !isCancelled ) {
let data = await AccessToken.getCurrentAccessToken();
let token = data.accessToken.toString();
// await afterLoginComplete(token);
const response = await fetch(
`https://graph.facebook.com/me?fields=id,email,name,first_name,last_name,gender,picture,cover&access_token=${token}`);
let result = await response.json();
this.setState({result});
console.log('result result result ', result);
//navigate to complete the registration.
this.props.navigation.navigate('Reg_1', {name: this.state.result.name, email: this.state.result.email, surname: this.state.result.last_name })
}
else {
console.log('Login incomplete');
}
}
Also I have this button to call the function:
<ButtonFB
onPress={ this._fbAuth}
isLoading={false}
isEnabled={true}
label={I18n.t("Accedi_con_Facebook")}
style={commonStyle.Button}
/>
Everything works fine and the data retrieved well. The only problem is the part of navigation and setSate. My problem is that the 'this' has been lost during the login with the facebook. I got the following warning after doing the login with facebook.
Possible: Unhandled promise rejection (id:0): type error:
this.setState is not a function
I also tried to bind the function of _fbAuth, but it doesn't work. Can you help me to solve this problem. Thanks in advance.

You need to bind the function as
_fbAuth = async () => {}
Since this is not being referenced in _fbAuth function.
For more info checkout this artice

Related

Redirecting from exported handle hook in sveltekit

I have a sveltekit app and I want to check if the user has an accesstoken from the cookie. I can access it through event.request.headers.get('cookie'); and redirects them to a certain route but I can't find specific syntax from the sveltekit docs.
src/hooks.ts
export async function handle({ event, resolve }) {
const reqCookie = event.request.headers.get('cookie');
const cookieName = 'userid';
const keeperCookie = reqCookie.split(';')
.find((c: string) => c.trim().startsWith(cookieName));
const response = await resolve(event);
if (!reqCookie || !keeperCookie) {
return response.headers.set('location', '/create');
}
return response.headers.set('location', '/login');
}
Redirect doesn't work for me and gives me an error in the console
I just got it using native Response
`return Response.redirect(baseUrl+"/login", 303);`
return new Response('Redirect', {status: 303, headers: { Location: '/login' }});
So you don't need the base url :)

Next JS router not changing page in async function

I am very new to promises and JS in general, but I am working on creating a register page using a tutorial on YouTube. I am currently using next.js with react and TypeScript to redirect to the user to the home page if no errors occur when registering (no email, password too short, etc.), but the router won't redirect the user within an async onSubmit function.
Here is the current non-working code. The useRegisterMutation hook just creates a function that takes in the input fields and creates a user in the db for me:
const Register: React.FC<registerProps> = ({}) => {
const router = useRouter();
const [register] = useRegisterMutation();
return (
<Wrapper>
<Formik initialValues={{first_name: "", last_name: "", email: "", password: ""}}
onSubmit={async (values, {setErrors}) => {
const response = await register({
variables: {
email: values.email,
pass: values.password,
fname: values.first_name,
lname: values.last_name
}
});
// A user is returned, meaning there were no errors
if (response.data?.createUser?.user) {
await router.push("/");
// An error was returned, meaning that the user was not created
} else if (response.data?.createUser?.errors) {
setErrors(setErrorMap(response.data.createUser.errors));
}
}}>
// ----------- Unimportant HTML -----------
</Formik>
</Wrapper>
);
}
export default Register;
When I remove async / await from the onSubmit function, the router begins correctly working, but the if statements do not work correctly because they are expecting response to be a promise, so they fail every time. Is there some trick to get the router to push to the correct url while still keeping the function as a promise?
Your async code seems to be fine, and you're saying the redirect works without async.
It seems that you might not be getting what you're expecting to get.
I'd log the response and response.data and all of the subsequent properties that you need for your if statement.
p.s.
Feel free to share the tutorial, you might've missed something or maybe it has a mistake.

stripe.redirectToCheckout parameter: price is not an accepted parameter react

I have an error I am running into on my stripe checkout in react... I have a button and when it is clicked, it is supposed to redirect to the stripe checkout page. However, I get the error
Uncaught (in promise) IntegrationError: Invalid stripe.redirectToCheckout parameter: price is not an accepted parameter.
this happens when I run this code -- this is my entire checkout.js page
import { loadStripe } from '#stripe/stripe-js';
import firebase from 'firebase';
import getStripe from './stripe';
const firestore = firebase.firestore();
export async function createCheckoutSession(){
// without uid
// return firestore.collection()
const checkoutSessionRef = await firestore.collection('profiledata').doc().collection('checkout_sessions').add(
// {price : 'price_1IGEdTKDPaWWeL1ymwWH5Ubb',
{price : '9.99',
success_url : window.location.origin,
// cancel_url: window.location.origin,
}
);
console.log("Before onSnapShot");
checkoutSessionRef.onSnapshot(async (snap) => {
const sessionid = snap.data();
console.log("Snap Data: ", snap.data());
console.log("Session ID: ", sessionid);
if (sessionid) {
console.log("Inside session ID: ", sessionid);
const stripe = loadStripe("pk_test_mystripeid")
stripe.redirectToCheckout(sessionid)
}
});
}
does anyone know why this is happening?
When creating a Checkout Session, line_items.price is a Price ID in the form of price_123, not an integer.
What is sessionid in this context? Is it a string or an object? Since you're using sessions it should be a string in the form of cs_test_123. What do your console.log's output? On what line is the error happening?
stripe.redirectToCheckout is an asynchronous method, but you're not catching any errors. Try something like this instead:
const result = await stripe.redirectToCheckout({
sessionId: session.id,
});
if (result.error) {
// If `redirectToCheckout` fails due to a browser or network
// error, display the localized error message to your customer
// using `result.error.message`.
}
You also don't appear to be using loadStripe correctly, as it's also an asynchronous method that returns a promise: https://github.com/stripe/stripe-js#loadstripe.
There's a lot going on here and not much info (for instance, what does getStripe do?). I suggest you take some time to read the react-stripe-js docs to familiarise yourself with the library and how to use it: https://github.com/stripe/react-stripe-js

React login using context API with private route

In my react web app, login-logout functionality is implemented using context-API and hooks. Everything seems to work fine except for the fact that I have to click the 'Login' button twice to push the user to the dashboard.
The statement, return <Redirect to="/dashboard /> does not work, instead I have to use history.push('/dashboard'), which does not seems to be a better option to me while login.
Here is the working snippet :
https://codesandbox.io/s/wizardly-worker-mqkex?file=/src/AuthContext.js
Also, I need some suggestions for the best practise to fetch the logged user details in other components. Using localstorage or global context API state, which of them serves as the best option for the same ?
Any help to resolve this, appreciated :)
Well, it boils down to the simple fact that your context is not updated when you do your check. The simplest solution would be to remove the check for isLoggedIn and push the user to the Dashboard:
const postLogin = async (e) => {
e.preventDefault()
try {
await login()
props.history.push('/dashboard')
} catch (error) {
dispatch({
type: 'LOGIN_FAILURE',
payload: 'Unable to login'
})
}
}
Then throw an error in your login function when you don't get a 200 back:
const login = async () => {
const loginUser = { status: 200, id: '3654634565659abhdgh' }
if (loginUser.status === 200) {
dispatch({
type: 'LOGIN_SUCCESS',
payload: loginUser.id
})
} else {
throw new Error("Invalid Credentials")
}
}
As your login code is in a try catch block, the user won't get pushed to the Dashboard when the login fails.

How to fix this function to handle different error type of error catching

I have developing mern stack web site. In that I have added below codes to handle logging.
onSubmit(e) {
e.preventDefault();
const obj = {
user_name: this.state.user_name,
password: this.state.password
};
axios.post('http://localhost:4000/login', obj)
.then(res=> localStorage.setItem('token',(res.data.token))
//localstorage.setItem('username','res.data.user.username)
)
}
When I click on login button this onSubmit() function called and will save token in local storage.
But, res.data have more details. (from backend it passes logged users information too)
So I want to add those to local storage. I tried that as commented in above function. It says error in res. Note : I user react for frontend.
Also I want to handle handle errors in any cases axios.post() didn't work as planned. In server side it send different messages for unmatched credentials and wrong passwords. How can I show those in my page. Thank you.
Since the only accepted data type in localStorage is string, you should stringify it first using JSON API.
const userDataStr = JSON.stringify(res.data);
localStorage.setItem('userData', userDataStr);
Now if you want to access the userData from localStorage you just need to convert it back to javascript object.
const userDataStr = localStorage.getItem('userData', userData);
const userData = JSON.parse(userDataStr);
You can have multiple catch in the returned promise of axios.post
axios.post()
.catch((error) => { })
.catch((error) => { })
But those catch will called with the same error so you need to handle it differently in each catch
Another suggestion:
If you want to easily handle the error, you can use higher order function like this
const handleError = (status, callback) => (error) => {
if (status === error) {
callback(error);
}
}
axios.post()
.catch(handleError(404, (error) => { /* only called when status === 404 */ }))
.catch(handleError(500, (error) => { /* only called when status === 500 */ }))

Resources