AsyncStorage not working properly with react native on android - android

AsyncStorage is not letting me overwrite or remove data.
This is my data
const allData = [
{
txnId: '012',
category: '',
time: 'Today, 2:00pm',
amount: 129,
type: 'Personal',
images: [],
},
{
txnId: '011',
category: '',
time: 'Today, 1:00pm',
amount: 20,
type: 'Personal',
images: [],
},
{
txnId: '010',
category: '',
time: 'Today, 10:00am',
amount: 200,
type: 'Personal',
images: [],
},
{
txnId: '009',
category: '',
time: 'Yesterday, 11:40pm',
amount: 649,
type: 'Personal',
images: [],
},
{
txnId: '008',
category: '',
time: 'Yesterday, 6:00pm',
amount: 200,
type: 'Personal',
images: [],
},
{
txnId: '007',
category: '',
time: 'Yesterday, 11:30am',
amount: 2200,
type: 'Personal',
images: [],
},
{
txnId: '006',
category: '',
time: 'Yesterday, 09:00am',
amount: 200,
type: 'Personal',
images: [],
},
{
txnId: '005',
category: '',
time: 'Yesterday, 10:00am',
amount: 200,
type: 'Personal',
images: [],
},
{
txnId: '004',
category: '',
time: 'Yesterday, 09:00am',
amount: 200,
type: 'Personal',
images: [],
},
{
txnId: '003',
category: 'Travel',
time: 'Today, 12:20pm',
amount: 2300,
type: 'Business',
status: 'Pending',
images: [],
},
{
txnId: '002',
category: 'Food',
time: 'Today, 12:02pm',
amount: 1000,
type: 'Business',
status: 'Rejected',
images: [],
},
{
txnId: '001',
category: 'Food',
time: 'Yesterday, 07:00am',
amount: 200,
type: 'Business',
status: 'Approved',
images: [],
}
];
The following functions are where I want to save and retrieve from AsyncStorage.
componentDidMount() {
AsyncStorage.getItem('allData').then(res => {
this.setState({
allData: JSON.parse(res),
});
});
console.log(this.state.allData);
}
componentWillUnmount() {
AsyncStorage.removeItem('allData');
AsyncStorage.setItem('allData', JSON.stringify(this.state.allData));
BackAndroid.removeEventListener('hardwareBackPress', this.handlesBackButton);
}
setCategory(index) {
const newData = this.state.allData.map((item, i) => {
const value = item;
if (i === index) {
value.type = item.type === 'Personal' ? 'Business' : 'Personal';
value.status = item.type === 'Personal' ? '' : 'Pending';
value.category = item.type === 'Personal' ? '' : 'Select category';
}
return value;
});
AsyncStorage.mergeItem('allData', JSON.stringify(newData));
this.setState({
allData: newData,
});
console.log(this.state.allData);
}
My render function contains the following
return (
<Transactions
allData={this.state.allData}
setCategory={(index, category) => {
const newData = this.state.allData.map((item, i) => {
const value = item;
if (index === i) {
value.category = category;
}
return value;
});
AsyncStorage.mergeItem('allData', JSON.stringify(newData));
this.setState({
allData: newData,
});
console.log(this.state.allData);
}}
onChange={this.setCategory.bind(this)}
/>);
There is nothing wrong with the state and props. Commenting out all the AsyncStorage stuff and logging the state and props gives expected result.
I think the main problem here is being caused by AsyncStorage.getItem. Without this method, all the functions and stuff work as expected. I tried putting it inside componentWillUpdate and componentWillMount as well and got the same result. What am I doing wrong?
Someone please help.

When you called AsyncStorage.getItem('allData'), The first item you get back from the promise is the error object. The second item will be the data you want.
Try this:
AsyncStorage.getItem('allData').then((error, res) => {
this.setState({
allData: JSON.parse(res),
});
});

Related

React native deep linking not moving through to 2nd deep link

When using react native deep linking, I am struggling to use a uri with a 2nd path. There are examples in the documentation https://reactnavigation.org/docs/4.x/deep-linking
The issue I am having is blahh://account --android will link to the correct screen however, blahh://account/keys --android will not. This is the same if I add any path to the screens in the AccountStack
I am using react navigation version 4.
const AccountStack = createStackNavigator(
{
Account: {
screen: Account,
path: '',
navigationOptions: {
...accountNavigationOptions,
...Account.navigationOptions,
},
},
AccountLoginAndSecurity: {
screen: AccountLoginAndSecurity,
path: '',
navigationOptions: () => ({
...defaultNavigationOptions,
headerTransitionPreset: 'uikit',
}),
},
CreateAccount: {
screen: CreateAccount,
path: '',
navigationOptions: () => ({
...defaultNavigationOptions,
headerTransitionPreset: 'uikit',
}),
},
KeysList: {
screen: KeysList,
path: 'keys',
navigationOptions: () => ({
...defaultNavigationOptions,
headerTransitionPreset: 'uikit',
}),
},
AccountSwitch: createAnimatedSwitchNavigator(
{
AccountLoading: {
screen: AccountLoading,
path: '',
params: {
theme: 'orange',
navigateScreen: 'CreateAccountOrLogin',
},
},
CreateAccountOrLogin: CreateAccountOrLogin,
Continue: AccountMenu,
},
{
initialRouteName: 'AccountLoading',
transition: createSwitchTransition(),
}
),
},
{
defaultNavigationOptions: accountNavigationOptions,
}
);
export const TabNavigator = createBottomTabNavigator(
{
Explore: {
screen: ExploreStack,
path: '',
},
Bookings: {
screen: YourBookingsStack,
path: '',
},
Account: {
screen: AccountStack,
path: 'account',
},
},
{
defaultNavigationOptions: ({ navigation }) => ({
// eslint-disable-next-line react/display-name
tabBarIcon: ({ focused }): React.ReactNode => {
const { routeName } = navigation.state;
let iconName;
if (routeName === 'Explore') {
focused
? (iconName = require('assets/icons/bottom_tab_icons/explore_tab_icon.png'))
: (iconName = require('assets/icons/bottom_tab_icons/explore_tab_icon_unselected.png'));
} else if (routeName === 'Bookings') {
focused
? (iconName = require('assets/icons/bottom_tab_icons/bookings_tab_icon.png'))
: (iconName = require('assets/icons/bottom_tab_icons/bookings_tab_icon_unselected.png'));
} else if (routeName === 'Account') {
focused
? (iconName = require('assets/icons/bottom_tab_icons/account_tab_icon.png'))
: (iconName = require('assets/icons/bottom_tab_icons/account_tab_icon_unselected.png'));
}
return <Image source={iconName} />;
},
tabBarOptions: {
showLabel: false,
style: {
elevation: 3,
borderTopColor: 'transparent',
backgroundColor: '#fff',
height: 50,
},
},
}),
navigationOptions: () => ({
headerBackTitle: null,
headerTitleStyle: { color: 'orange' },
}),
}
);
I just looked at the codebase and Account links through to the account screen before going to the keys screen.
Account: {
screen: Account,
path: '',
navigationOptions: {
...accountNavigationOptions,
...Account.navigationOptions,
},
},
so the fix was to add an empty path to this in the accountstack then it worked fine when going to npx uri-scheme open blahh://account/keys --android

React native F2 chart does not show up on android

Does anyone knows why it does not show up on android? it works perfectly fine on iOS. I'm using this lib btw https://github.com/aloneszjl/react-native-f2chart. In example, it seems to work with both iOS and android, but I can't get it to work on android. Any help would be appreciated
const HomeTab = () => {
const data = [
{
date: '2017-06-05',
value: 116,
},
{
date: '2017-06-06',
value: 129,
},
{
date: '2017-06-07',
value: 135,
},
];
const initScript = data => `
(function(){
chart = new F2.Chart({
id: 'chart',
pixelRatio: window.devicePixelRatio,
});
chart.source(${JSON.stringify(data)}, {
value: {
tickCount: 5,
min: 0
},
date: {
type: 'timeCat',
range: [0, 1],
tickCount: 3
}
});
chart.tooltip({
custom: true,
showXTip: true,
showYTip: true,
snap: true,
crosshairsType: 'xy',
crosshairsStyle: {
lineDash: [2]
}
});
chart.axis('date', {
label: function label(text, index, total) {
var textCfg = {};
if (index === 0) {
textCfg.textAlign = 'left';
} else if (index === total - 1) {
textCfg.textAlign = 'right';
}
return textCfg;
}
});
chart.line().position('date*value');
chart.render();
})();
`;
return(
<View style={{ height: 200, width: 400}}>
<Chart
style={{flex: 1, width: 400}}
initScript={initScript(data)}
/>
</View>
)
}

Expo FCM push notification sound not working

I have tried this code:
const sendPushNotification = async (vendor_token, user_message) => {
const message = {
to: vendor_token,
priority: Platform.OS === 'android' ? "normal" : "high",
sound: "default",
title: 'Order Detail',
body: user_message,
data: { data: 'goes here' },
_displayInForeground: true,
};
const response = await fetch('https://exp.host/--/api/v2/push/send', {
method: 'POST',
headers: {
Accept: 'application/json',
'Accept-encoding': 'gzip, deflate',
'Content-Type': 'application/json',
},
body: JSON.stringify(message),
});
const data = response._bodyInit;
console.log(`Status & Response ID-> ${JSON.stringify(data)}`);
};
But if add sound: true for Android notification not working.
const sendPushNotification = async (vendor_token, user_message) => {
const message = {
to: vendor_token,
priority: Platform.OS === 'android' ? "normal" : "high",
sound: "default",
title: 'Order Detail',
body: user_message,
data: { data: 'goes here' },
_displayInForeground: true,
channelId: "chat-messages",`enter code here`
};
const response = await fetch('https://exp.host/--/api/v2/push/send', {
method: 'POST',
headers: {
Accept: 'application/json',
'Accept-encoding': 'gzip, deflate',
'Content-Type': 'application/json',
},
body: JSON.stringify(message),
});
const data = response._bodyInit;
console.log(`Status & Response ID-> ${JSON.stringify(data)}`);
};
Just add "channelId: "chat-messages" in the code and android notification sound is working perfectly

React Native FlatList Grid custom view

I am developing a react native app that shows data in the flatlist grid view.
for that, I followed the code which I found on the expo. I work fine. But what I need is, I want the first row should render one item only. so that I can use the empty space to show some data first.
here is the Expo link.
https://snack.expo.io/#savadks1818/react-native-flatlist-grid
and here is the code
import React from 'react';
import { StyleSheet, Text, View, FlatList, Dimensions } from 'react-native';
const data = [
{ key: 'A' }, { key: 'B' }, { key: 'C' }, { key: 'D' }, { key: 'E' }, { key: 'F' }, { key: 'G' }, { key: 'H' }, { key: 'I' }, { key: 'J' },
{ key: 'K' },
// { key: 'L' },
];
const formatData = (data, numColumns) => {
const numberOfFullRows = Math.floor(data.length / numColumns);
let numberOfElementsLastRow = data.length - (numberOfFullRows * numColumns);
while (numberOfElementsLastRow !== numColumns && numberOfElementsLastRow !== 0) {
data.push({ key: `blank-${numberOfElementsLastRow}`, empty: true });
numberOfElementsLastRow++;
}
return data;
};
const numColumns = 3;
export default class App extends React.Component {
renderItem = ({ item, index }) => {
if (item.empty === true) {
return <View style={[styles.item, styles.itemInvisible]} />;
}
return (
<View
style={styles.item}
>
<Text style={styles.itemText}>{item.key}</Text>
</View>
);
};
render() {
return (
<FlatList
data={formatData(data, numColumns)}
style={styles.container}
renderItem={this.renderItem}
numColumns={3}
/>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
marginVertical: 20,
},
item: {
backgroundColor: '#4D243D',
alignItems: 'center',
justifyContent: 'center',
flex: 1,
margin: 3,
height: Dimensions.get('window').width / numColumns, // approximate a square
},
itemInvisible: {
backgroundColor: 'transparent',
},
itemText: {
color: '#fff',
},
});
you can do this by adding new obects in the data array in desired position
const data = [
{ key: 'A' },
{ empty: true, key: 'xxx' },
{ empty: true, key: 'xxx' },
{ key: 'B' },
{ key: 'C' },
{ key: 'D' },
{ key: 'E' },
{ key: 'F' },
{ key: 'G' },
{ key: 'H' },
{ key: 'I' },
{ key: 'J' },
{ key: 'K' },
{ key: 'L' },
];
to add item do
data.splice(1, 0, { empty: true, key: 'xxx' });

remove title bar or add button to it in sencha

This is screenshot of my sencha app deployed on android. I view two blue bars on the top. what i want is just to remove one of them. Any idea how to do it?
The codeis given below. hope this will help
Ext.define('appointMeDr.view.signUp.SignUp',{
extend:'Ext.form.Panel',
xtype:'signUpXType',
config:{
scrollable:'vertical',
items:[
{
xtype: 'toolbar',
title: 'Sign Up',
docked: 'top',
items:[ {
xtype:'button',
text: 'Back',
ui: 'back',
cls: 'back',
name: 'backToLogin'
}
]
},
{
xtype:'fieldset',
defaults :{
labelWidth : '120px'
},
items:[
{
xtype:'textfield',
label:'<sup>*</sup> Full Name: ',
placeHolder:'Full Name',
name:'name'
},
{
xtype: 'emailfield',
label: '<sup>*</sup> Email',
placeHolder:'Email',
name: 'email'
},
{
xtype:'textfield',
label:'<sup>*</sup> User Name: ',
placeHolder:'User Name',
name:'username'
},
{
xtype: 'passwordfield',
label: '<sup>*</sup> Password',
placeHolder:'Password',
name: 'password'
},
{
xtype:'textfield',
label:'<sup>*</sup> Age: ',
placeHolder:'Age',
name:'age'
},
{
xtype: 'selectfield',
name:'gender',
label: 'Gender',
options: [
{
text: 'Male',
value: 'Male'
},
{
text: 'Female',
value: 'Female'
}
]
},
{
xtype:'textfield',
label:'<sup>*</sup> Address : ',
placeHolder:'Address',
name:'address'
},
{
xtype: 'selectfield',
name:'Domain',
label: 'Select Domain',
options: [
{
text: 'Patient',
value: 'first'
},
{
text: 'Doctor',
value: 'second'
},
{
text: 'Guardian',
value: 'third'
},
{
text: 'Attendant',
value: 'forth'
}
]
}
]
},{
xtype:'panel',
margin:'10px',
items:[
{
xtype:'button',
text:'Sign Up',
flex:1,
name:'userSignUpBtn',
docked:'right'
}
]
}
]
}
});
youre probably using a navigation view and loading another panel which contains a toolbar into the navigation view so what you get is
1. blue bar from the navigation view
2. 2nd blue bar from the panel view
What you could do is load the view directly into the viewport instead of the navigation view
hope this helps :)

Categories

Resources