React Native - Why isn't the function getting called? - javascript

I have a function inside another function that won't get called.
First function:
const getToken = dispatch => async () => {
try {
GoogleSignin.configure({
webClientId: 'XXXX',
iosClientId: 'XXXX',
});
const {idToken} = await GoogleSignin.signIn();
const googleCredential =
firebase.auth.GoogleAuthProvider.credential(idToken);
const userCredential = await firebase
.auth()
.signInWithCredential(googleCredential);
const token = userCredential.user.uid;
secondFunction(token);
} catch (err) {
dispatch({
type: 'error_1',
payload: 'error',
});
}
};
2nd function:
const secondFunction = dispatch => token => {
console.log('second function called');
try {
axios.post(url, token).then(res => {
console.log(res.data);
const response = res.data;
} catch (err) {
dispatch({
type: 'error_1',
payload: 'error',
});
}
};
might be something simple I'm not getting. Would appreciate any help!

Should be
secondFunction(dispatch)(token)
Because your console.log was inside nested function

Related

How do I access an exported function in another exported function in same file?

I am trying to fetch the user data in the login function from the loadUser function. But it is refusing to run, I am not sure what is wrong here?
I think you can call an exported function in the same file?
// Login User
export const login = (formData) => async dispatch => {
const config = {
heraders: {
'Content-Type': 'application/json'
}
}
try {
const res = await axios.post('/api/auth', formData, config);
dispatch({
type: LOGIN_SUCCESS,
payload: res.data
});
console.log('Calling load user here?');
loadUser();
console.log('loadUser did not run?');
} catch (err) {
dispatch({
type: LOGIN_FAIL,
payload: err.response.data.msg
});
}
}
// Load User
export const loadUser = () => async dispatch => {
console.log('Is this running');
if (localStorage.token) {
setAuthToken(localStorage.token);
}
console.log('GETTING USER');
try {
const res = await axios.get('/api/auth');
dispatch({
type: USER_LOADED,
payload: res.data
});
} catch (err) {
dispatch({
type: AUTH_ERROR
});
}
}
I expect the loadUser function to run, but it don't.
You should be able to call the loadUser function from within the login function by its name like you would any other JavaScript function.
Here is how you can update the login function to call the loadUser function:
// Login User
export const login = (formData) => async dispatch => {
const config = {
headers: {
'Content-Type': 'application/json'
}
}
try {
const res = await axios.post('/api/auth', formData, config);
dispatch({
type: LOGIN_SUCCESS,
payload: res.data
});
console.log('Calling load user here?');
// Call the loadUser function, passing in dispatch as an argument
loadUser()(dispatch);
console.log('loadUser did not run?');
} catch (err) {
dispatch({
type: LOGIN_FAIL,
payload: err.response.data.msg
});
}
}
Since the loadUser function is an async function that takes dispatch as an argument, you will need to call it like this: loadUser()(dispatch).

TypeError: Cannot read properties of undefined (reading 'protocol') in React using Axios

So basically as the APP.js renders it is not sending requests to the backend. I am calling the currentUser function inside App.js function. Please help me I am stuck
app.js file
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged(async (user) => {
if (user) {
const getidtoken = await user.getIdTokenResult();
currentUser(getidtoken.token)`enter code here`
.then((res) => {
console.log(res);
dispatch({
type: 'LOGGED_IN_USER',
payload: {
email: res.data.email,
name: res.data.name,
role: res.data.role,
_id: res.data._id,
},
});
})
.catch((err) => {
console.log(err);
});
}
});
currentuser.js Function
export const currentUser = async (authtoken) => {
return await axios.post(
process.env.REACT_APP_API_USER,
{},
{ headers: { authtoken: authtoken } }
);
};
enter image description here

Call Firebase Function in javascript

I have a Cloud Function deployed to Firebase, and my iOS and Android apps use it fine, all works good. Below is the function deployed.
const admin = require('firebase-admin');
const firebase_tools = require('firebase-tools');
const functions = require('firebase-functions');
admin.initializeApp();
exports.deleteUser = functions
.runWith({
timeoutSeconds: 540,
memory: '2GB'
})
.https.onCall((data, context) => {
const userId = context.auth.uid;
var promises = [];
// DELETE DATA
var paths = ['users/' + userId, 'messages/' + userId, 'chat/' + userId, 'like/' + userId];
paths.forEach((path) => {
promises.push(
recursiveDelete(path).then( () => {
return 'success';
}
).catch( (error) => {
console.log('Error deleting user data: ', error);
})
);
});
// DELETE FILES
const bucket = admin.storage().bucket();
var image_paths = ["avatar/" + userId, "avatar2/" + userId, "avatar3/" + userId];
image_paths.forEach((path) => {
promises.push(
bucket.file(path).delete().then( () => {
return 'success';
}
).catch( (error) => {
console.log('Error deleting user data: ', error);
})
);
});
// DELETE USER
promises.push(
admin.auth().deleteUser(userId)
.then( () => {
console.log('Successfully deleted user');
return true;
})
.catch((error) => {
console.log('Error deleting user:', error);
})
);
return Promise.all(promises).then(() => {
return true;
}).catch(er => {
console.error('...', er);
});
});
function recursiveDelete(path, context) {
return firebase_tools.firestore
.delete(path, {
project: process.env.GCLOUD_PROJECT,
recursive: true,
yes: true,
token: functions.config().fb.token
})
.then(() => {
return {
path: path
}
}).catch( (error) => {
console.log('error: ', error);
return error;
});
}
// [END recursive_delete_function]
How can I execute this script with a button in javascript? A standard .js file locally? I also need to be able to pass in a userId manually.
In my react native app I call it like:
const deleteUser = async () => {
functions().httpsCallable('deleteUser')()
signOut();
}
But in my javascript file (nothing to do with my react native app), I need to pass in a userId and call that same function to delete the user.
There are a number of ways to go about executing a cloud function within your client side application.
Depending on how you have the function setup, you can either pass in a parameter or data via the body in the request.
For example, using express (similar to other frameworks):
// fetch(‘api.com/user/foo’, {method: ‘DELETE’} )
app.delete(‘/user/:uid’, (req, res) => {
const uid = req.params.uid;
// execute function
})
// fetch(‘api.com/user’, {method: ‘DELETE’, body: { uid: foo } } )
app.delete(‘/user’, (req, res) => {
const uid = req.body.uid;
// execute function
})
// fetch(‘api.com/user?uid=foo’, {method: ‘DELETE’} )
app.delete(‘/user’, (req, res) => {
const uid = req.query.uid;
// execute function
})
Full Example:
<button onclick=“deleteUser(uid)”>Delete Me</button>
<script>
function deleteUser(uid) {
fetch(`api.com/user/${uid}`, { method: ‘DELETE’});
// rest of function
}
</script>
Was able to call my firebase function with the following:
userId was accessible like so const { userId } = data; from my function script
async function deleteAccount(userId) {
const deleteUser = firebase.functions().httpsCallable("deleteUser");
deleteUser({ userId }).then((result) => {
console.log(result.data);
});
}

TypeError: Cannot read property 'type' of undefined in react js

I am using jumbo 4.1.1 template. I get the response, but this error occurs.
My code is below:
authAction.js:
...
export const userSignIn = (user) => {
// const {email, password} = user;
console.log(user)
axios.post(base_url +'login', user)
.then(response=> {
console.log(response.data)
return {
type: SIGNIN_USER,
payload: user
};
})
};
But when I run the project, I got the error TypeError: Cannot read property 'type' of undefined
I believe that is because you have not dispatched the action properly.
Are you using thunk?
If you are using Redux and making an async call, you should return dispatch.
const userSignup = (signupData) => {
return async (dispatch) => {
try {
let res = await axios.post(`${url}/user/`, { user: signupData });
dispatch({
type: "FETCH_CURRENT_USER_SUCCESS",
payload: res.data.user,
});
return true;
} catch (error) {
console.log(
"%c CATCH in userSignup ",
"background: red; color: #bada55",
error
);
}
};
};
Notice, that I am returning a function with dispatch as an argument in the second line. and then using that dispatch (4th line) that dispatches the action's type and payload.
Also I'm returning something from the function userSignUp, finally, so the invoker of the function userSignUp gets something in response.
If you don't understand anything above, please do let me know.
You could benefit from using async + await here.
For example:
export const userSignIn = async (user) => {
try {
// const {email, password} = user;
console.log(user);
const data = await axios.post(base_url +'login', user);
console.log(data);
return {
type: SIGNIN_USER,
payload: user,
};
} catch (error) {
console.log(error);
// return an error action...?
return {
type: ERROR,
payload: error,
};
}
};

Service call is not going in react-native. Getting warning like "Possible unhandled Promise Rejection, Reference error: response is not defined"

I am new to react native and making service call for the first time. My problem is service call is not going and getting warning like
Possible unhandled Promise Rejection, Reference error: response is not defined.
I am trying to hit loginUser function.
Api.js
const BASE_URL = "http://localhost:8200";
export const api = async (url, method, body = null, headers = {}) => {
try {
const endPoint = BASE_URL.concat(url);
const reqBody = body ? JSON.stringify(body) : null;
const fetchParams = {method, headers};
if((method === "POST" || method === "PUT") && !reqBody) {
throw new Error("Request body required");
}
if(reqBody) {
console.log("ReQBody--->"+reqBody);
fetchParams.headers["Content-type"] = "application/json";
fetchParams.body = reqBody;
}
const fetchPromise = await fetch(endPoint, fetchParams);
const timeOutPromise = new Promise((resolve, reject) => {
setTimeout(() => {
reject("Request Timeout");
}, 3000);
});
const response = await Promise.race([fetchPromise, timeOutPromise]);
return response;
} catch (e) {
return e;
}
}
export const fetchApi = async (url, method, body, statusCode, token = null, loader = false) => {
console.log("In FetchAPi Function");
try {
const headers = {}
const result = {
token: null,
success: false,
responseBody: null
};
if(token) {
headers["securityKey"] = token;
}
const response = await api(url, method, body, headers);
console.log("fetchApi-->>"+response);
if(response.status === statusCode) {
result.success = true;
let responseBody;
const responseText = await response.text();
try {
responseBody = JSON.parse(responseText);
} catch (e) {
responseBody = responseText;
}
result.responseBody = responseBody;
return result;
}
let errorBody;
const errorText = await response.text();
try {
errorBody = JSON.parse(errorText);
} catch (e) {
errorBody = errorText;
}
result.responseBody = errorBody;
console.log("FetchApi(Result)--->>"+result);
throw result;
} catch (error) {
return error;
}
}
auth.actions.js
export const loginUser = (payload) => {
console.log("In LoginUser function2");
return async (dispatch) => {
<-----**I am not able to enter into this block**------>
try {
dispatch({
type: "LOGIN_USER_LOADING"
});
console.log("In LoginUser function3");
const response = await fetchApi("/login", "POST", payload, 200);
if(response.success) {
dispatch({
type: "LOGIN_USER_SUCCESS",
});
dispatch({
type: "AUTH_USER_SUCCESS",
token: response.token
});
dispatch({
type: "GET_USER_SUCCESS",
payload: response.responseBody
});
return response;
} else {
throw response;
}
} catch (error) {
dispatch({
type: "LOGIN_USER_FAIL",
payload: error.responseBody
});
return error;
}
}
}
In console log, I can't see anything in network tab. In the android emulator, the mentioned warning has come.
My console tab
I see that your BASE_URL is served using an http endpoint. You can only make requests to https endpoints from react native projects. A possible workaround is to use ngrok. Just download it and run ./ngrok http 8200 since your port number is 8200. It will expose an HTTPS endpoint and replace your BASE_URL with that link and try fetching the data again.
I use the following code to make API calls. See if you can integrate it in your code. it is quite simple:
In a class called FetchService:
class FetchService {
adminAuth(cb, data) {
console.log('here in the fetch service');
return fetch(
baseURL + "login",
{
method: "POST",
headers: {
Accept: "application/json",
},
body: data
}
)
.then((response) => response.json())
.then(responsej => {
cb(null, responsej);
})
.catch(error => {
cb(error, null);
});
}
}
export default FetchService;
Then call it from your component using:
import FetchService from './FetchService';
const fetcher = new FetchService;
export default class LoginScreen extends React.Component {
fetchData() {
const data = new FormData();
data.append('username',this.state.username);
data.append('password',this.state.password);
fetcher.wastereport((err, responsej) => {
if(err) {
//handle error here
} else {
//handle response here
}
}, data);
}
}

Categories

Resources