React Native Logout Using Access Token Error - react-native

This is a simple app to login with API and logout. I retrieved Access Token when login. I navigated the access token to sidebar and trying to log out using logout function
SideBar.js
import React from 'react';
import { Text, Alert } from 'react-native';
import { Drawer,Container, Content, Header, Right, Button } from 'native-base';
export default class SideBar extends React.Component {
constructor(props) {
super(props)
this.state = {
token: this.props.usertoken
}
}
UserLogoutFunction = () =>{
const { token } = this.state;
fetch('https://api.idepoz.com/ncl/api/logout', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Authorization': `Bearer ${token}`,
},
body: JSON.stringify({
})
}).then((response) => response.json())
.then((responseJson) => {
console.log("token");
if(responseJson)
{
this.props.navigation.navigate('Login');
Alert.alert("Succesfully Logged Out");
}
else{
Alert.alert(responseJson);
}
}).catch((error) => {
console.error(error);
});
}
render() {
return (
<Container>
<Header>
</Header>
<Content>
<Button transparent onPress={ this.UserLogoutFunction } >
<Text style={{fontSize: 24}}>Log Out</Text>
</Button>
</Content>
</Container>
);
}
}
It returning NETWORK REQUEST FAILED.
The below function returned access token while login
UserLoginFunction = () =>{
const { UserName } = this.state ;
const { UserPassword } = this.state ;
fetch('https://api.idepoz.com/ncl/api/login', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
username: UserName,
password: UserPassword
})
}).then((response) => response.json())
.then((responseJson) => {
if(responseJson)
{
this.props.navigation.navigate('QrScan',{usertoken:responseJson.token});
}
else{
Alert.alert(responseJson);
}
}).catch((error) => {
console.error(error);
});
}
Please tell what's wrong with the "UserLogoutFunction"

Related

React Native RNPicker select

i am using RNPicker Select in which i want dropdown items to get from api but i am getting empty dropdown with no values
following is my code
class Component extends Component {
constructor(props) {
super(props);
this.state = {
inqSourceList: [],
}
componentDidMount() {
this.fetchSource();
}
fetchSource = () => {
getInqSourceList('view=select', this, null)
}
<RNPickerSelect
items={this.state.inqSourceList}
name="source"
value={this.state.source ? this.state.source.id : null}
onValueChange={value => {
this.setState({
source:value,
});
}}
style={{marginBottom: 10}}
/>
and my api code is
export async function getModuleList (moduleName, params,error) {
let token = await AsyncStorage.getItem('token');
axios
.get(BASE_URL + moduleName + "?" + params, {
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: "Bearer " + token },
})
.then((res) => {
var bytes = CryptoJS.AES.decrypt(res.data.toString(), ENCDEC);
res.data = JSON.parse(bytes.toString(CryptoJS.enc.Utf8));
// success(res.data);
// console.log(res.data)
})
.catch(error);
}
in this i am getting values from backend when i use console.log(res.data) i get list of options..but the dropdown item is empty..
thanks
here is the function where inqSourceList is set
export function getInqSourceList(params, _this, next) {
getModuleList('settings/inquiry-source', params, data => {
_this.setState({inqSourceList: data.rows});
if (next) next(data);
});
}

Handling Refresh Token in React Native

I have an app authenticating fine and returning the access_token and refresh_token. I store them with AsyncStorage and save/get the access_token with redux. This is the very first app I am building and I am struggling with how and where to use the refresh_token.
This is the axios call in the component loginForm.js
axios({
url: `${base}/oauth/token`,
method: 'POST',
data: formData,
headers: {
Accept: 'application/json',
'Content-Type': 'multipart/form-data',
}
})
.then(response => {
setStatus({ succeeded: true });
// console.log(response.data);
deviceStorage.saveKey("userToken", response.data.access_token);
deviceStorage.saveKey("refreshToken", response.data.refresh_token);
Actions.main();
})
.catch(error => {
if (error.response) {
console.log(error);
}
});
This is the service deviceStorage.js
import { AsyncStorage } from 'react-native';
const deviceStorage = {
async saveItem(key, value) {
try {
await AsyncStorage.setItem(key, value);
} catch (error) {
console.log('AsyncStorage Error: ' + error.message);
}
}
};
export default deviceStorage;
This is the token action file
import { AsyncStorage } from 'react-native';
import {
GET_TOKEN,
SAVE_TOKEN,
REMOVE_TOKEN,
LOADING_TOKEN,
ERROR_TOKEN
} from '../types';
export const getToken = token => ({
type: GET_TOKEN,
token,
});
export const saveToken = token => ({
type: SAVE_TOKEN,
token
});
export const removeToken = () => ({
type: REMOVE_TOKEN,
});
export const loading = bool => ({
type: LOADING_TOKEN,
isLoading: bool,
});
export const error = tokenError => ({
type: ERROR_TOKEN,
tokenError,
});
export const getUserToken = () => dispatch =>
AsyncStorage.getItem('userToken')
.then((data) => {
dispatch(loading(false));
dispatch(getToken(data));
})
.catch((err) => {
dispatch(loading(false));
dispatch(error(err.message || 'ERROR'));
});
export const saveUserToken = (data) => dispatch =>
AsyncStorage.setItem('userToken', data)
.then(() => {
dispatch(loading(false));
dispatch(saveToken('token saved'));
})
.catch((err) => {
dispatch(loading(false));
dispatch(error(err.message || 'ERROR'));
});
export const removeUserToken = () => dispatch =>
AsyncStorage.removeItem('userToken')
.then((data) => {
dispatch(loading(false));
dispatch(removeToken(data));
})
.catch((err) => {
dispatch(loading(false));
dispatch(error(err.message || 'ERROR'));
});
This is the token reducer file
import {
GET_TOKEN,
SAVE_TOKEN,
REMOVE_TOKEN,
LOADING_TOKEN,
ERROR_TOKEN
} from '../actions/types';
const INITIAL_STATE = {
token: {},
loading: true,
error: null
};
export default (state = INITIAL_STATE, action) => {
switch (action.type) {
case GET_TOKEN:
return {
...state,
token: action.token
};
case SAVE_TOKEN:
return {
...state,
token: action.token
};
case REMOVE_TOKEN:
return {
...state,
token: action.token
};
case LOADING_TOKEN:
return {
...state,
loading: action.isLoading
};
case ERROR_TOKEN:
return {
...state,
error: action.error
};
default:
return state;
}
};
And this is the authentication file
import React from 'react';
import {
StatusBar,
StyleSheet,
View,
} from 'react-native';
import { connect } from 'react-redux';
import { Actions } from 'react-native-router-flux';
import { Spinner } from '../common';
import { getUserToken } from '../../actions';
class AuthLoadingScreen extends React.Component {
componentDidMount() {
this.bootstrapAsync();
}
bootstrapAsync = () => {
this.props.getUserToken().then(() => {
if (this.props.token.token !== null) {
Actions.main();
} else {
Actions.auth();
}
})
.catch(error => {
this.setState({ error });
});
};
render() {
return (
<View style={styles.container}>
<Spinner />
<StatusBar barStyle="default" />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center'
},
});
const mapStateToProps = state => ({
token: state.token,
});
const mapDispatchToProps = dispatch => ({
getUserToken: () => dispatch(getUserToken()),
});
export default connect(mapStateToProps, mapDispatchToProps)(AuthLoadingScreen);
I believe I need to create an action and reducer to get the refresh_token (is that correct?) but I do not know what to do with it and where to call it (perhaps in the authentication file?).
Any help with this possibly with code examples related to my code would be massively appreciated. Thanks
Below are the steps
Do Login , get accessToken , refreshToken from response and save it to AsyncStorage.
Make common function for API calling
async function makeRequest(method, url, params, type) {
const token = await AsyncStorage.getItem('access_token');
let options = {
method: method,
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: 'Bearer ' + token,
},
};
if (!token) {
delete options['Authorization'];
}
if (['GET', 'OPTIONS'].includes(method)) {
url += (url.indexOf('?') === -1 ? '?' : '&') + queryParams(params);
} else {
Object.assign(options, {body: JSON.stringify(params)});
}
const response = fetch(ENV.API_URL+url, options);
return response;
}
Make one method in redux for getAceessTokenFromRefreshToken.
Use this method when session is expired
How do you know session is expired?
From each API calling if you get response like (440 response code) in
async componentWillReceiveProps(nextProps) {
if (nextProps.followResponse && nextProps.followResponse != this.props.followResponse) {
if (nextProps.followResponse.status) {
if (nextProps.followResponse.status == 440) {
// call here get acceesstokenfrom refresh token method and save again accesstoken in asyncstorage and continue calling to API
}
}
}
}

Getting Undefined in React native

import React, { Component } from 'react';
import { View, Text } from 'react-native';
class HttpExample extends Component {
state = {
data: ''
}
componentDidMount = () => {
fetch("https://jsonplaceholder.typicode.com/posts/1", { --this is fake url
method: 'POST',
headers: new Headers({
'Content-Type': 'application/x-www-form-urlencoded', // <-- Specifying the Content-Type
}),
body: "param1=value1&param2=value2" // <-- Post parameters
})
.then((response) =>
response.text()
)
.then((responseText) => {
alert(responseText.id);
this.setState({
data: responseText
})
})
.catch((error) => {
console.error(error);
});
}
render() {
return (
<View>
<Text>
{this.state.data.id}
</Text>
</View>
)
}
}
export default HttpExample;
if i use alert(ResponseText)
in alert i am getting o/p but as i tried to have individual value from my object it returns undefined
o/p: "id": "1",
"computeId": "USR00001" in alert
.then((response) => response.text())
to
.then((response) => response.json())
I guess you need json style response.

react-native Can't display value got in my fetch

I can't display the values ​​retrieved from my fetch to my
This is my code, but I get 'null is not an object' :
import React, {Component} from 'react';
import { StyleSheet, Image, Text, View, TextInput, StatusBar, Button,
AppRegistry, TouchableHighlight, TouchableOpacity } from 'react-native';
import AndroidBackButton from 'react-native-android-back-button'
import { StackNavigator } from 'react-navigation'
export default class ComponenFive extends React.Component {
getInfos(){
fetch('http://172.16.101.183:3000/users', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
requestType: 'infosCompte'
})
})
.then((response) => response.json())
.then((res) => {
this.setState({username: res.username, nom: res.nom, prenom: res.prenom, lieu: res.lieu, batiment: res.batiment, bureau: res.bureau});
})
.done();
}
render() {
{this.getInfos}
return (
<View style={{backgroundColor: 'white', flex: 1}}>
<Text>Identifiant : {this.state.username}</Text>
</View>
)
}
}
Do you have any idea to help me ?
using fetch you are getting more than just the data on json.
try this example
fetch('http://172.16.101.183:3000/users', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
requestType: 'infosCompte'
})
})
.then(response => response.json().then(json => ({ json, response })))
.then(({ json, response }) => {
if (!response.ok) {
return Promise.reject(json);
}
return json;
})
.then((res) => {
this.setState({username: res.username, nom: res.nom, prenom: res.prenom, lieu: res.lieu, batiment: res.batiment, bureau: res.bureau});
})
.done();
UPDATE:
Sorry just seen your code and is not correct. Using {this.getInfos} on render() is wrong. getInfo is just a function. You dont return anything. If you want to call this function as it is use componentWillMount and set the state on constructor
constructor(props) {
super(props);
this.state = {username: '', nom: ''};
}
componentWillMount() {
this.getInfos()
}
res already json. pull the data directly from the res.
console.log(res);
let resData = JSON.parse(res._bodyText);
this.setState({username: resData.username, nom: resData.nom, .....})

Cannot able to navigate to another screen in react native

I have made login authentication using POST API, I received success response, inside success response, I just want to navigate to other screen say for e.g(from Login screen to Videos screen).But it's not working for me pls look at my code and tell me where I made mistakes.
index.android.js:
export default class Registration extends Component {
render() {
const { navigation } =this.props;
return (
<Login navigation={ navigation }/>);
}
}
src/Login.js:
class Login extends Component {
constructor(props) {
super(props);
this.redirect=this.redirect.bind(this)
this.state = {
email: '',
password: '',
errors: '',
}
}
On button submit i just calling below method
CallSignIn() {
fetch("http://localhost:3000/users/login", { method: "POST", body: JSON.stringify({ email: this.state.email, password: this.state.password }), headers: { 'x-api-key': '7LH9ElCr4p1GLiMXAWLu0a9UsvKZ4wJr7t1N3ewh', 'Content-Type': 'application/json' } })
.then((response) => response.json())
.then((responseData) => {
this.setState({ showProgress: false })
this.redirect()
Alert.alert("success:", JSON.stringify(responseData.token));
})
.done();
}
redirect() {
const { navigate } = props.navigation;
navigate('Videos')
}
}