React Native RNPicker select - react-native

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);
});
}

Related

Axios throws an "unauthorized" at me

This is strange because postman allows me to make a POST however react does not. the token is valid and when called, the token prints to console
export default class Create extends Component {
//url = 'http://127.0.0.1:5000/wtw/articles/'
constructor(props) {
super(props);
this.state = {
//author?
title: '',
description: '',
//image: ,
//token: null
};
}
handleCreate = async () => {
const { title, description, image } = this.state;
let token = await AsyncStorage.getItem('token');
axios
.post('http://127.0.0.1:5000/wtw/articles/', {
headers: {
Authorization: 'Token ' + token,
},
data: {
title: title,
description: description,
},
})
.then(async (Response) => {
console.log(Response);
})
.catch((err) => {
console.log();
console.log(err);
console.log(token);
});
};
}

React Native Logout Using Access Token Error

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"

Unable to set state from the response of the api

I have a following function in Api.js
const _getCategories = async () => {
var categories = [];
let token = await getJwt();
var config = {
method: 'get',
url: 'myurl',
headers: {
'Authorization': 'Bearer' + ' ' + token
},
data : ''
};
axios(config)
.then(function (response) {
if(response.status == 200)
{
let res = response.data;
// Create a variable having name in the list.
categories = res.data.apps.map(function(item) {
return {
title: item.name,
color: AppStyles.colorSet.analyticsColor,
lightColor: AppStyles.colorSet.analyticsLightColor,
icon: AppStyles.iconSet.analytics
};
});
// console.log('Returning Categories');
console.log(categories);
return categories;
//console.log(data1)
// Handle and fetch the list of apps
}
else
{
// API didn't go through, generate the error functions
}
})
.catch(function (error) {
console.log(error);
});
};
and I am loading it in homscreen.js
class DashboardScreen extends React.Component {
constructor(props) {
super(props);
const { navigation } = props;
navigation.setOptions({
title: 'Dashboard',
headerLeft: () => (
<TouchableOpacity
onPress={() => {
navigation.openDrawer();
}}
>
<Icon
style={AppStyles.styleSet.menuButton}
name="ios-menu"
size={AppStyles.iconSizeSet.normal}
color={AppStyles.colorSet.mainThemeForegroundColor}
/>
</TouchableOpacity>
),
});
this.state = {
categories: [],
};
}
componentDidMount() {
if (!this.state.data) {
Api.getCategories().then(data => console.log("The data is "+data))
.catch(err => { /*...handle the error...*/});
}
}
onPressCategory = item => {
// Handle onpress for the items
};
render() {
//console.log(this.state.categories);
categoryButtonsRow1 = this.state.categories.map((item, index) => {
if (index < 3) {
return (
<CategoryButton
onPress={() => this.onPressCategory(item)}
color={item.color}
lightColor={item.lightColor}
icon={item.icon}
title={item.title}
/>
);
}
});
return (
<ScrollView style={styles.container}>
<View style={styles.row}>{categoryButtonsRow1}</View>
</ScrollView>
);
}
}
But I am getting category as undefined while printing in render().
I even tried to create an async function in the homescreen.js and call the api with await and set the state after the same but still it is coming as undefined.
Any guesses to what I am doing wrong here. Can anyone help with the same. My best guess is that I am not handling the api request properly.
EDIT
I tried Use Async/Await with Axios in React.js but it is still printing undefined to the same.
The reason for getting undefined is the _getCategories is that its not returning anything and you are chaining using .then to get data so the caller has no way to get this data as a callback is not passed.
You can change the to await like this
const _getCategories = async () => {
var categories = [];
let token = await getJwt();
var config = {
method: 'get',
url: 'myurl',
headers: {
Authorization: 'Bearer' + ' ' + token,
},
data: '',
};
const response = await axios(config);
if (response.status == 200) {
let res = response.data;
// Create a variable having name in the list.
categories = res.data.apps.map(function (item) {
return {
title: item.name,
color: AppStyles.colorSet.analyticsColor,
lightColor: AppStyles.colorSet.analyticsLightColor,
icon: AppStyles.iconSet.analytics,
};
});
// console.log('Returning Categories');
console.log(categories);
return categories;
//console.log(data1)
// Handle and fetch the list of apps
} else {
// API didn't go through, generate the error functions
return null;
}
};
And you can set the state in componentDidMount (should be async)
this.setState({categories:await api._getCategories()});

React Native accessing SecureStore

I have searched Google for a clear answer on this but cant find one. Below is my code.
In a previous screen I have stored the token to SecureStore
I'm now trying to access it from a different screen.
(async () => {
const token = await SecureStore.getItemAsync('token');
return token;
})();
export default class App extends React.Component {
constructor(){
super();
this.state = {
data: [],
loaded: true,
error: null,
token: token
}
}
Can anyone advise me how to get the value from SecureStore to my state inside the class?
Entire Code
import React, { Component} from 'react';
import { Text, Button, ScrollView } from 'react-native';
import { globalStyles } from '../styles/global';
import * as SecureStore from 'expo-secure-store';
(async () => {
const token = await SecureStore.getItemAsync('token');
//console.log('token output 1 ' + token);
return token;
})();
export default class App extends React.Component {
constructor() {
super();
this.state = {
data: [],
loaded: true,
error: null,
token: ""
};
}
baseURL = 'https://www.example.co.uk/api/auth';
getData = (ev)=>{
this.setState({loaded:false, error: null});
let url = this.baseURL + '/list';
let h = new Headers();
console.log('token output 2 = ' + this.state.token);
h.append('Authorization', 'Bearer tokenToBePutHere');
h.append('Content-Type', 'application/json');
h.append('X-Requested-With', 'XMLHttpRequest');
let req = new Request(url, {
headers: h,
method: 'GET'
});
fetch(req)
.then(response=>response.json())
.then(this.showData)
.catch(this.badStuff)
}
showData = (data)=>{
this.setState({loaded:true, data:data});
}
badStuff = (err) => {
this.setState({loaded: true, error: err.message});
}
componentDidMount() {
(async () => {
const token = await SecureStore.getItemAsync('token');
this.setState({ token });
})();
this.getData();
}
render() {
return (
<ScrollView style={globalStyles.container}>
{ !this.state.loaded && (
<Text>LOADING</Text>
)}
<Text>Your Lists Are:</Text>
{/*} <Button title="Get Data"
onPress={this.getData} /> */}
{ this.state.error && (
<Text style={styles.err}>{this.state.error}</Text>
)}
{ this.state.data && this.state.data.length > 0 && (
this.state.data.map( data => (
<Text key={data.id}>
{ data.lists.name }
</Text>
))
)}
</ScrollView>
);
}
}
I have added all of my code for this screen.
token Output 1 works and outputs the correct token
token Output 2 does not work and returns nothing.
I need to use the token in the api call but cant get it to pass there.
You can use the lifecycle method componentDidMount and callbacks like this:
export default class App extends React.Component {
constructor() {
super();
this.state = {
data: [],
loaded: true,
error: null,
token: ""
};
}
componentDidMount() {
SecureStore.getItemAsync("token").then(token => {
this.setState({ token });
});
}
// ...
}
Same solution using async/await:
class App extends React.Component {
constructor() {
super();
this.state = {
data: [],
loaded: true,
error: null,
token: '',
};
}
componentDidMount() {
(async () => {
const token = await SecureStore.getItemAsync('token');
this.setState({ token });
})();
}
// ...
}
Addressing updated question
If you need only need the token for the fetch request you don't even need to store the token in the state. You can use it directly after retrieving it from SecureStore:
componentDidMount() {
(async () => {
const token = await SecureStore.getItemAsync('token');
// Your fetch code
this.setState({loaded:false, error: null});
let url = this.baseURL + '/list';
let h = new Headers();
h.append('Authorization', `Bearer ${token}`);
h.append('Content-Type', 'application/json');
h.append('X-Requested-With', 'XMLHttpRequest');
let req = new Request(url, {
headers: h,
method: 'GET'
});
fetch(req)
.then(response=>response.json())
.then(() => this.setState({loaded:true, data:data}))
.catch(() => this.badStuff())
})();
}

React Native: setState doesn't work when calling try-catch function

I tried to call APP with this code imported from another file and it worked fine:
import FormData from 'FormData';
import AsyncStorage from '#react-native-community/async-storage';
let formData = new FormData();
formData.append('userId', '1'); // < this is what I want to change
formData.append('key', '***'); //my key
export function getScoreFromAPI () {
return fetch('https://www.globalfidelio.com/gfn_arcol/api/transaction.php',{
method : 'POST',
headers : {
'Accept': 'application/json',
'Content-Type': 'multipart/form-data'
},
body : formData
} )
.then((response) => {
return response.json()
})
.catch((error) => console.log("l'erreure est: " + error))
}
but now I want to change my userId from 1 to an constante from Asyncstorage, so I decide to change my code to this:
constructor(props) {
super(props)
this.state = { infos: [], userId: '' }
}
componentWillMount() {
this.getScoreFromAPI().then(data => {
this.setState({ infos: data })
});
console.log(this.state.infos);
AsyncStorage.getItem(USERID_STORED)
.then((data) => {
if (data) {
this.setState({userId:data})
}
});
}
async getScoreFromAPI() {
let formData = new FormData();
formData.append('userId', this.state.userId);
formData.append('key', '***'); //my key
try {
let response = await fetch('https://www.globalfidelio.com/gfn_arcol/api/transaction.php',{
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'multipart/form-data'
},
body: formData
})
let res = await response.json();
} catch(error) {
console.warn("errors are " + error);
}
};
with a try-catch function but when I call getScoreFromAPI() in ComponentWillMount() I can't setState with received data, I still have an empty array in info:[]
my questions:
how can I replace '1' in userId by a value in asyncstorage in the first file ?
if it isn't possible, what I have do to setState info: [] with my data reveived
I've simplified your code into a promise chain in which calling getScoreFromAPI will execute after getting the userId from AsyncStorage, then storing the response into the infos state, while returning null if there was an error, and logging the error to the console. The data was not previously returned from getScoreFromAPI, so the value would always become null. I have not tested this code, but this should give you a good base to work from:
import FormData from 'FormData';
import AsyncStorage from '#react-native-community/async-storage';
export default class Test {
constructor() {
this.state = {
infos: null,
userId: ''
};
}
componentDidMount() {
AsyncStorage.getItem(this.state.userId)
.then(userID => {
this.setState({ userId: userID || '' });
})
.then(() => {
return this.getScoreFromAPI();
})
.then(data => {
this.setState({ infos: data });
})
.catch(console.error);
}
getScoreFromAPI = () => {
const formData = new FormData();
formData.append('userId', this.state.userId);
formData.append('key', '***'); //my key
fetch('https://www.globalfidelio.com/gfn_arcol/api/transaction.php', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'multipart/form-data'
},
body: formData
})
.then(response => {
// use response data here
return response.json();
})
.catch(e => {
console.error(e);
return null;
});
};
}
You're doing your API call before fetching your value from AsyncStorage (I know this is async but it's not very readable if you do it that way).
getScoreFromAPI doesn't return anything, that's why your setState isn't working.
You don't need to use try and catch here, promises have their own error handling mechanism (the .catch() method).
I think callbacks are more readable and lead to less bugs than using .then() in code.
This is how I would do it:
constructor(props)
{
super(props);
this.state = { infos: [], userId: '' };
this.onSuccess = this.onSuccess.bind(this);
this.onFailure = this.onFailure.bind(this);
}
componentWillMount()
{
// Get userID from local storage, then call your API
AsyncStorage.getItem(YOUR_KEY)
.then(userID=> {
if (userID)
{
this.setState({ userId : userID }, () => {
this.getScoreFromAPI(this.onSuccess, this.onFailure);
});
}
});
}
onSuccess(data)
{
this.setState({
infos : data
});
}
onFailure(err)
{
console.warn('Error ' + err);
}
getScoreFromAPI(onSuccess, onFailure)
{
let formData = new FormData();
formData.append('userId', this.state.userId);
formData.append('key', '***'); //your key
fetch('https://www.globalfidelio.com/gfn_arcol/api/transaction.php', {
method : 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'multipart/form-data'
},
body: formData
})
.then(res => res.json())
.then(json => {
onSuccess(json);
})
.catch(err => {
onFailure(err);
});
}
It's finally done. I tried this and it worked. Thank you to all of you
this is what I have done:
...
const USERID_STORED = "userid_stored";
const GSM_STORED = "gsm_stored";
...
class ScoreList extends React.Component {
constructor(props) {
super(props)
this.state = { infos: [], userId: '', gsmStored: '', }
}
componentWillMount() {
AsyncStorage.getItem(USERID_STORED)
.then(userId => {
this.setState({ userId: userId});
this.getScoreFromAPI(this.state.userId).then(data => {
this.setState({ infos: data });
});
});
AsyncStorage.getItem(GSM_STORED)
.then(gsmStore => {
this.setState({ gsmStored: gsmStore});
});
}
getScoreFromAPI (userId) {
let formData = new FormData();
formData.append('userId', userId);
formData.append('key', '***');
return fetch('https://***',{
method : 'POST',
headers : {
'Accept': 'application/json',
'Content-Type': 'multipart/form-data'
},
body : formData
} )
.then((response) => {
return response.json()
})
.catch((error) => console.log("l'erreure est: " + error))
};