Here is my code:
response.data.data.map((item, index) => {
console.log('response',item);
const itemIndex = dataList.findIndex(v => v.dt3 === item.dt3);
if (itemIndex > -1) {
//update quantity in list if same item is selected more than one time
const value = {
ds: item.ds,
bl: item.bl,
mty: item.od_auto.Mty,
name: item.customer_name_auto,
};
dataList.push(value);
} else {
const value = {
ds: item.ds,
bl: item.bl,
mty: item.od_auto.Mty,
name: item.customer_name_auto,
};
dataList.push(item.dt3);
for(let i = 0; i<dataList.length; i++){
dataList[i] = value;
}
}
});
Expected output:
const DATA = [
{
title: '4th April, 2020',
data: [
{
ds: item.ds,
bl: item.bl,
mty: item.od_auto.Mty,
name: item.customer_name_auto,
},{
ds: item.ds,
bl: item.bl,
mty: item.od_auto.Mty,
name: item.customer_name_auto,
}
],
},
{
title: '3rd April, 2020',
data: [
{
ds: item.ds,
bl: item.bl,
mty: item.od_auto.Mty,
name: item.customer_name_auto,
},{
ds: item.ds,
bl: item.bl,
mty: item.od_auto.Mty,
name: item.customer_name_auto,
}
],
},
{
title: '2nd April, 2020',
data: [
{
ds: item.ds,
bl: item.bl,
mty: item.od_auto.Mty,
name: item.customer_name_auto,
},{
ds: item.ds,
bl: item.bl,
mty: item.od_auto.Mty,
name: item.customer_name_auto,
}
],
},
{
title: '1st April, 2020',
data: [
{
ds: item.ds,
bl: item.bl,
mty: item.od_auto.Mty,
name: item.customer_name_auto,
},{
ds: item.ds,
bl: item.bl,
mty: item.od_auto.Mty,
name: item.customer_name_auto,
}
],
},
];
This is how my API response looks:
{
"status": 1,
"data": [
{
"aid": 188427,
"s": 1,
"dt": "19th Oct 2022",
"dt3": "19-10-2022",
"ds": "Proceeds",
"cr": 172,
"bk": "sdlsjkfhjdfhgf",
"bkid": 1,
"up": "",
"od": {
"Mty": "",
"Mre": "",
"Mct": "",
"Mci": "",
"Mdt": "",
"Mdi": ""
},
"typ": "",
"cnm": "",
"tm": "19th Oct 2022 19:31",
"bl": "224",
"od_auto": {
"Mty": "Services",
"Mci": 77,
"Mct": 2,
"Mre": "",
"Mdt": "",
"Mdi": ""
},
"customer_name_auto": null
},
{
"aid": 188426,
"s": 2,
"dt": "19th Oct 2022",
"dt3": "19-10-2022",
"ds": "cslkdjfhsjkdfhjshfjs",
"cr": 1.01,
"bk": "slkdjfhsjkdfhljdfh",
"bkid": 397,
"up": "",
"od": {
"Mty": "",
"Mre": "",
"Mct": "",
"Mci": "",
"Mdt": "",
"Mdi": ""
},
"typ": "",
"cnm": "",
"tm": "19th Oct 2022 18:07",
"bl": "2487.22",
"od_auto": {
"Mty": "djfdfhghgh",
"Mci": 181,
"Mct": 1,
"Mre": "",
"Mdt": "",
"Mdi": ""
},
"customer_name_auto": "skdhfshdghsd"
},
]}
I am fetching the response from API to create Inverted flatlist. In my response array I have date object for each item in the array. Now I want to group the items which has same date in an array. How can I arrange the array items?
if you want to group your array of objects based on the date attribute then you can use this function
const data_array = {
"status": 1,
"data": [
{
"aid": 188427,
"s": 1,
"dt": "19th Oct 2022",
"dt3": "19-10-2022",
"ds": "Proceeds",
"cr": 172,
"bk": "sdlsjkfhjdfhgf",
"bkid": 1,
"up": "",
"od": {
"Mty": "",
"Mre": "",
"Mct": "",
"Mci": "",
"Mdt": "",
"Mdi": ""
},
"typ": "",
"cnm": "",
"tm": "19th Oct 2022 19:31",
"bl": "224",
"od_auto": {
"Mty": "Services",
"Mci": 77,
"Mct": 2,
"Mre": "",
"Mdt": "",
"Mdi": ""
},
"customer_name_auto": null
},
{
"aid": 188426,
"s": 2,
"dt": "19th Oct 2022",
"dt3": "19-10-2022",
"ds": "cslkdjfhsjkdfhjshfjs",
"cr": 1.01,
"bk": "slkdjfhsjkdfhljdfh",
"bkid": 397,
"up": "",
"od": {
"Mty": "",
"Mre": "",
"Mct": "",
"Mci": "",
"Mdt": "",
"Mdi": ""
},
"typ": "",
"cnm": "",
"tm": "19th Oct 2022 18:07",
"bl": "2487.22",
"od_auto": {
"Mty": "djfdfhghgh",
"Mci": 181,
"Mct": 1,
"Mre": "",
"Mdt": "",
"Mdi": ""
},
"customer_name_auto": "skdhfshdghsd"
},
]}
var groupBy = function(xs, key) {
return xs.reduce(function(rv, x) {
(rv[x[key]] = rv[x[key]] || []).push(x);
return rv;
}, {});
};
console.log(groupBy(data_array.data, 'dt3'));
You can group your array with any object attribute:
let data_group_by_date = groupBy(data_array.data, 'dt3')
You can u section list data with the this code:
const sections_list_data = [];
Object.keys(data_group_by_date).map((item, i) => {
sections.push({
title: item,
data: data_group_by_date[item],
});
});
Add this Modules> Modify it a little bit.
import React, {useCallback, useEffect, useState} from 'react';
import {
ActivityIndicator,
SectionList,
StyleSheet,
Text,
TextInput,
TouchableOpacity,
View,
} from 'react-native';
import Modal from 'react-native-modal';
import {RFValue} from 'react-native-responsive-fontsize';
import Entypo from 'react-native-vector-icons/Entypo';
import FontAwesome from 'react-native-vector-icons/FontAwesome';
import {hp, wp} from '../constants/scaling';
import {colors, fonts} from '../constants/theme';
import {titleCase} from '../functions/commonfunction';
import {textStyles} from '../styles/textStyles';
const Item = ({item}) => {
return (
<View
style={{
width: wp(90),
height: hp(6),
alignItems: 'center',
flexDirection: 'row',
borderBottomColor: colors.inputBgColor,
borderBottomWidth: 1,
}}>
<FontAwesome
name={'map-marker'}
style={{marginRight: wp(2)}}
color={'#a1aac4'}
size={wp(6)}
/>
<Text
numberOfLines={1}
style={{
...textStyles.Label,
textAlign: 'center',
fontFamily: fonts.Medium,
}}>
{item.name}
</Text>
</View>
);
};
const SectionListDropDown = ({
isModalVisible,
setIsModalVisible,
setSelectedValue,
}) => {
const [loading, setLoading] = useState(false);
const [suggestionsList, setSuggestionsList] = useState([]);
const [search, setSearch] = useState('');
useEffect(() => {
if (search.trim().length > 2) {
ur_api_call_here_and_other_logic (search);
}
}, [search]);
const ur_api_call_here_and_other_logic = () => {
}
return (
<Modal
style={{
justifyContent: 'flex-end',
margin: 0,
}}
useNativeDriver={true}
backdropColor={colors.primaryColor}
backdropOpacity={1}
hideModalContentWhileAnimating={true}
backdropTransitionOutTiming={0}
animationInTiming={500}
animationOutTiming={500}
isVisible={isModalVisible}
onBackdropPress={setIsModalVisible}>
<View style={styles.main_view}>
<View
style={{
width: wp(90),
flexDirection: 'row',
alignItems: 'center',
//backgroundColor: colors.inputBgColor,
height: hp(7),
marginBottom: wp(2),
}}>
<TouchableOpacity onPress={setIsModalVisible}>
<Entypo name="cross" size={wp(7)} color={colors.textPrimaryColor} />
</TouchableOpacity>
<Text
style={{
...textStyles.heading,
marginLeft: wp(4),
fontFamily: fonts.Bold,
}}>
Departure
</Text>
</View>
<SectionList
showsVerticalScrollIndicator={false}
sections={suggestionsList}
ListEmptyComponent={
<Text
style={{
...textStyles.Label,
textAlign: 'center',
fontFamily: fonts.Bold,
}}>
Please Enter a least three characters
</Text>
}
scrollEventThrottle={500}
ListHeaderComponent={
<TouchableOpacity
style={{
backgroundColor: colors.inputBgColor,
height: hp(7),
alignItems: 'center',
flexDirection: 'row',
paddingHorizontal: wp(5),
borderRadius: wp(2),
marginBottom: wp(2),
width: wp(90),
}}>
<FontAwesome
name={'circle-o'}
style={{marginRight: wp(2)}}
color={'#a1aac4'}
size={wp(6)}
/>
<TextInput
value={search}
onChangeText={text => setSearch(text)}
placeholderTextColor={colors.secondaryTextColor}
placeholder="Search here your destination"
style={{
width: wp(72),
fontFamily: fonts.Medium,
includeFontPadding: false,
borderRadius: wp(2),
paddingHorizontal: wp(2),
backgroundColor: colors.inputBgColor,
justifyContent: 'center',
color: colors.textPrimaryColor,
fontSize: RFValue(14),
alignItems: 'center',
alignSelf: 'center',
height: hp(7),
}}
/>
</TouchableOpacity>
}
keyExtractor={(item, index) => item + index}
renderItem={({item}) => <Item item={item} />}
renderSectionHeader={({section: {title}}) => (
<View
style={{
backgroundColor: colors.primaryColor,
width: wp(90),
height: hp(7),
flexDirection: 'row',
marginVertical: wp(2),
borderRadius: wp(1),
alignItems: 'center',
paddingHorizontal: wp(2),
}}>
{title == 'hotels' ? (
<FontAwesome
name={'hotel'}
style={{marginRight: wp(2)}}
color={'#fff'}
size={wp(6)}
/>
) : (
<FontAwesome
name={'circle-o'}
style={{marginRight: wp(2)}}
color={'#fff'}
size={wp(6)}
/>
)}
<Text
style={{
...textStyles.heading,
fontFamily: fonts.Bold,
color: colors.white,
}}>
{titleCase(title)}
</Text>
</View>
)}
/>
{loading && (
<View style={styles.loadingView}>
<ActivityIndicator color={colors.textPrimaryColor} size={'large'} />
</View>
)}
</View>
</Modal>
);
};
export default SectionListDropDown;
const styles = StyleSheet.create({
main_view: {
justifyContent: 'center',
backgroundColor: colors.white,
//borderTopLeftRadius: wp(5),
padding: wp(5),
paddingVertical: wp(2),
flex: 1,
//borderTopRightRadius: wp(5),
},
});
Related
what happens is the following fact: I want to add "switch/toggle" next to id 2.3 and 4 items, but it's getting on all items on the flatlist. I used "import SwitchSelector from "react-native-switch-selector"; " Can anyone who understands flatlist help me? I will be very happy and grateful
I'm not getting it at all, and I'm thinking of redoing my code because of this problem
Settings.js
import { SafeAreaView,Text, View, FlatList,
TouchableOpacity, StyleSheet, Image} from 'react-native';
import SwitchSelector from "react-native-switch-selector";
import React, {useState} from 'react'
const Settings = () => {
const [data, setdata] = useState(DATA);
const [isRender, setisRender] = useState(false);
const DATA = [
{id: 1, text: 'Perfil', image: require('../../assets/images/user.png')},
{id: 2, text: 'Dark/Light mode', image: require('../../assets/images/light-up.png')},
{id: 3, text: 'TouchId', image: require('../../assets/images/fingerprint.png')},
{id: 4, text: 'Notificações', image: require('../../assets/images/bell-fill.png')},
//{id: 5, text: 'Logout'},
]
const renderItem = ({item}) => {
return(
<TouchableOpacity style= {styles.item}>
<View style={ styles.avatarContainer }>
<Image source={ item.image } style={ styles.avatar } />
</View>
<View>
<Text style={styles.text}>{item.text}</Text>
</View>
</TouchableOpacity>
)
}
return (
<SafeAreaView style={styles.container}>
<FlatList
data={DATA}
keyExtractor={(item) => item.id.toString()}
renderItem={renderItem}
extraData={isRender}
/>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
marginTop: 20
//marginHorizontal: 21
},
item:{
borderBottomWidth: 1,
borderBottomColor: '#808080',
alignItems: 'flex-start',
flexDirection: 'row',
},
avatarContainer: {
backgroundColor: 'transparent',
//borderRadius: 100,
height: 30,
width: 30,
justifyContent: 'center',
alignItems: 'center'
},
avatar: {
height: 25,
width: 25,
bottom: -25,
marginLeft: 30
},
text:{
marginVertical: 30,
fontSize: 20,
fontWeight: 'bold',
marginLeft: 30,
marginBottom: 10,
bottom: 5
}
});
export default Settings;
Well here is my approach to your problem as much as I understood;
it also actively changes the values of data for further usage of App
const [data, setData] = useState([
{ id: 1, text: 'Perfil', image: require('../../assets/images/user.png'), chosen: false },
{ id: 2, text: 'Dark/Light mode', image: require('../../assets/images/light-up.png'), chosen: false },
{ id: 3, text: 'TouchId', image: require('../../assets/images/fingerprint.png'), chosen: false },
{ id: 4, text: 'Notificações', image: require('../../assets/images/bell-fill.png'), chosen: false },
//{id: 5, text: 'Logout'},
])
const [isRender, setisRender] = useState(false);
const renderItem = ({ item }) => {
return (
<TouchableOpacity style={styles.item}>
<View style={styles.avatarContainer}>
<Image source={item.image} style={styles.avatar} />
</View>
<View>
<Text style={styles.text}>{item.text}</Text>
</View>
{item.id > 1 && <Switch
thumbColor={item.chosen == false ? "red" : "green"}
value={item.chosen}
onChange={() => setData(data.map(index =>
item.id === index.id
? {...index, chosen : !index.chosen}
: index
))}
/>}
</TouchableOpacity>
)
}
return (
<SafeAreaView style={styles.container}>
<FlatList
data={data}
keyExtractor={(item) => item.id.toString()}
renderItem={renderItem}
extraData={isRender}
/>
</SafeAreaView>
);};
You could try adding a boolean property to each item in DATA. You could then conditionally show a <SwitchSelector /> in renderItem based on that property.
For example, below I added the property showSwitch and used a ternary expression to conditionally show a <SwitchSelector /> in renderItem:
const DATA = [
{id: 1, text: 'Perfil', image: require('../../assets/images/user.png'), showSwitch: false},
{id: 2, text: 'Dark/Light mode', image: require('../../assets/images/light-up.png'), showSwitch: true},
{id: 3, text: 'TouchId', image: require('../../assets/images/fingerprint.png'), showSwitch: true},
{id: 4, text: 'Notificações', image: require('../../assets/images/bell-fill.png'), showSwitch: true},
//{id: 5, text: 'Logout'}
]
...
const renderItem = ({ item }) => {
return (
<TouchableOpacity style={styles.item}>
<View style={styles.avatarContainer}>
<Image source={item.image} style={styles.avatar} />
</View>
<View>
<Text style={styles.text}>{item.text}</Text>
</View>
{item.showSwitch ? <SwitchSelector /> : null}
</TouchableOpacity>
);
};
This works from me:
import { SafeAreaView,Text, View, FlatList,
TouchableOpacity, StyleSheet, Image, Switch} from 'react-native';
import React, {useState, useEffect} from 'react';
import {TouchID} from 'react-native-touch-id';
const Settings = () => {
const [data, setdata] = useState(DATA);
const [isRender, setisRender] = useState(false);
const DATA = [
{id: 1, text: 'Perfil', image: require('../../assets/images/user.png'), switch: false},
{id: 2, text: 'Dark/Light mode', image: require('../../assets/images/light-up.png'), switch: true},
{id: 3, text: 'TouchId', image: require('../../assets/images/fingerprint.png'), switch: true},
{id: 4, text: 'Notificações', image: require('../../assets/images/bell-fill.png'), switch: true},
//{id: 5, text: 'Logout'}
]
const renderItem = ({item}) => {
return(
<TouchableOpacity
style= {styles.item}
>
<View style={ styles.avatarContainer }>
<Image source={ item.image } style={ styles.avatar } />
</View>
<View>
<Text style={styles.text}>{item.text}</Text>
</View>
{item.switch ? <Switch /> : null}
</TouchableOpacity>
)
}
return (
<SafeAreaView style={styles.container}>
<FlatList
data={DATA}
keyExtractor={(item) => item.id.toString()}
renderItem={renderItem}
extraData={isRender}
/>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
marginTop: 20
//marginHorizontal: 21
},
item:{
borderBottomWidth: 1,
borderBottomColor: '#808080',
alignItems: 'flex-start',
flexDirection: 'row',
},
avatarContainer: {
backgroundColor: 'transparent',
//borderRadius: 100,
height: 30,
width: 30,
justifyContent: 'center',
alignItems: 'center',
},
avatar: {
height: 25,
width: 25,
bottom: -25,
marginLeft: 30
},
text:{
marginVertical: 30,
fontSize: 20,
fontWeight: 'bold',
marginLeft: 30,
marginBottom: 10,
bottom: 5
},
});
export default Settings;
I want to select one item from each ListItem. But the problem is that I can only choose one item at a time. I have used multiselect, but the problem is there is that multiple items could be selected from each section item.
**
I want to access one data from every list in react native listitem.I
want to select one item from each ListItem. But the problem is that I
can only choose one item at a time. I have used multiselect, but the
problem is there is that multiple items could be selected from each
section item.I have used flatlist then in renderitem I have used
listItem.
**
ProductAttributes:Object {
"Id": 9,
"Name": "Size",
"Values": Array [
Object {
"ColorSquaresRgb": null,
"CustomProperties": Object {},
"FullSizePictureUrl": null,
"Id": 21,
"IsPreSelected": false,
"Name": "8",
"PictureId": 0,
"PictureUrl": null,
"PriceAdjustment": null,
"PriceAdjustmentValue": 0,
},
Object {
"ColorSquaresRgb": null,
"CustomProperties": Object {},
"FullSizePictureUrl": null,
"Id": 22,
"IsPreSelected": false,
"Name": "9",
"PictureId": 0,
"PictureUrl": null,
"PriceAdjustment": null,
"PriceAdjustmentValue": 0,
},
],
}
ProductAttributes: Object {
"Id": 10,
"Name": "Color",
"Values": Array [
Object {
"ColorSquaresRgb": "#663030",
"CustomProperties": Object {},
"FullSizePictureUrl": "img1",
"Id": 25,
"IsPreSelected": true,
"Name": "Red",
"PictureId": 53,
"PictureUrl": "img2",
"PriceAdjustment": null,
"PriceAdjustmentValue": 0,
},
Object {
"ColorSquaresRgb": "#363656",
"CustomProperties": Object {},
"FullSizePictureUrl": "img3",
"Id": 26,
"IsPreSelected": false,
"Name": "Blue",
"PictureId": 54,
"PictureUrl": "img4",
"PriceAdjustment": null,
"PriceAdjustmentValue": 0,
},
],
}
And the UI is
<FlatList
data={this.state.product_attributes2}
ListHeaderComponent={null}
renderItem={({ item, index }) => {
console.log("ProductAttributes: ", item);
return (
<>
<ListItem.Accordion
style={{ height: 50 }}
content={
<>
<Iconsss
name="filter-menu"
size={20}
style={{ marginRight: 10 }}
/>
<ListItem.Content>
<ListItem.Title>{item.Name}</ListItem.Title>
</ListItem.Content>
</>
}
isExpanded={this.state.expanded}
onPress={() => {
this.setState({ expanded: !this.state.expanded });
}}
>
<View
style={{
borderTopWidth: 1,
borderColor: "rgba(38, 38, 38,0.8)",
}}
>
{item?.Values?.map((l, i) => {
return (
<ListItem
key={i}
onPress={() => {
console.log(l.IsPreSelected);
this.setState({
select_choice: true,
choice_name: l.Name,
// IsPreSelected:l.IsPreSelected,
});
}}
bottomDivider
Checkbox
>
<ListItem.CheckBox
// checked={this.state.IsPreSelected}
checked={l.IsPreSelected === true ? true : false}
onPress={() =>
this.setState({ IsPreSelected: !l.IsPreSelected })
}
/>
<ListItem.Content>
<ListItem.Title
style={{ color: "rgba(38, 38, 38,1)" }}
>
{l.Name}
</ListItem.Title>
</ListItem.Content>
{l?.ColorSquaresRgb === null ? null : (
<View
style={{
backgroundColor: l?.ColorSquaresRgb,
height: 20,
// width:20,
borderRadius: 20,
flex: 0.3,
justifyContent: "center",
// alignItems:"center",
}}
/>
)}
{l?.PictureUrl === null ? null : (
<Image
source={{ uri: l.PictureUrl }}
style={{
flex: 0.7,
resizeMode: "contain",
height: 50,
}}
/>
)}
</ListItem>
);
})}
</View>
</ListItem.Accordion>
</>
);
}}
keyExtractor={(item, index) => {
return index.toString();
}}
ListFooterComponent={null}
/>
How to remove space between flex. (spaces is marked in green)
I am currently using flex-wrap: 'wrap', and flat list with 2 columns. I am trying to archive something like google keep
My code:-
<FlatList
data={[
{ storeName: 'The Look' },
{ storeName: 'STYLO' },
{ storeName: 'Bombshell studio' },
{ storeName: 'STYLO1' },
{ storeName: 'The Look2' },
{ storeName: 'STYLOe' },
{ storeName: 'STYdLO1' },
{ storeName: 'Thed Look2' },
{ storeName: 'STdYLOe' },
]}
numColumns={2}
columnWrapperStyle={{
flex: 1,
flexWrap: 'wrap',
flexDirection: 'row',
alignItems: 'flex-start',
paddingLeft: 15,
}}
containerStyle={{
width: '100%',
}}
renderItem={({ item }) => (
<ARecentBooking key={item.storeName} storeName={item.storeName} />
)}>
</FlatList>
You can implement the UI as shown below
import * as React from 'react';
import { Text, View, StyleSheet, FlatList, Dimensions } from 'react-native';
import Constants from 'expo-constants';
const DeviceWidth = Dimensions.get('window').width;
export default function App() {
const renderItem = ({ item }) => (
<View style={styles.Card}>
{/* ALl Other COde here...Like the 15 AUG and everything */}
</View>
);
return (
<View style={styles.container}>
<FlatList
data={[
{ storeName: 'The Look' },
{ storeName: 'STYLO' },
{ storeName: 'Bombshell studio' },
{ storeName: 'STYLO1' },
{ storeName: 'The Look2' },
{ storeName: 'STYLOe' },
{ storeName: 'STYdLO1' },
{ storeName: 'Thed Look2' },
{ storeName: 'STdYLOe' },
]}
numColumns={2}
columnWrapperStyle={{
flex: 1,
flexWrap: 'wrap',
flexDirection: 'row',
}}
containerStyle={{
width: '100%',
}}
renderItem={renderItem}></FlatList>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: Constants.statusBarHeight,
backgroundColor: 'white',
},
Card: {
flex: 1,
backgroundColor: '#FFEAEC',
minHeight: 150,
margin: 10,
borderRadius: 12,
maxWidth: DeviceWidth / 2 - 20,
},
});
Here is a Snack for the same.
Here's a Screenshot of the result.
method 1:- I manage to get the result with some workaround:-
<ScrollView style={{flexDirection:'row'}}>
//put two faltlist
<Flatlist scrollEnabled={false}/>
<Flatlist scrollEnabled={false}/>
<ScrollView/>
put items of the odd index in the first flatlist
and even items in the second flatList
function separateArrays(array) {
let arr1=[]
let arr2=[]
for(i=0; i<array.length; i++) {
if(i%2 === 0) {
arr1.push(array[i])
}
else{
arr2.push(array[i])
}
}
return [arr1, arr2]
}
method 2:-It also can be done using .map function
<ScrollView>
<View style={{ flexDirection: 'row', paddingLeft: 15 }}>
<View>
{arr1.map((item, index) => {
return <ARecentBooking key={item.storeName} item={item} />
})}
</View>
<View>
{arr2.map((item, index) => {
return <ARecentBooking key={item.storeName} item={item} />
})}
</View>
</View>
</ScrollView>
I want to store username to local storage using #react-native-async-storage/async-storage in React Native. When I checked through console.log, username was saved successfully but while retrieving the data back to different screen using getData function, It says null. Help me to figure out the issue.
this is my storage.js file where I've kept all the Async Storage functions.
import AsyncStorage from '#react-native-async-storage/async-storage';
const storeData = async (key, value) => {
try {
await AsyncStorage.setItem(key, value)
} catch (e) {
console.log('Error on saving')
}
}
const getData = async (key) => {
try {
const value = await AsyncStorage.getItem(key)
if (value !== null) {
console.log('Promise', value)
return value
}
} catch (e) {
// error reading value
}
}
export { storeData, getData };
this is my Log In Screen file
import React, { Component, useState } from 'react';
import { View, Text, Button, ScrollView, TextInput, TouchableHighlight, StyleSheet } from 'react-native';
import * as yup from 'yup'
import { Formik } from 'formik'
import { storeData } from '../utils/storage';
const Login = (props) => {
const handleLogin = (name) => {
storeData('username',name)
props.navigation.navigate('Home')
}
return (
<Formik
initialValues={{
name: '',
password: ''
}}
onSubmit={values => Alert.alert(JSON.stringify(values))}
validationSchema={yup.object().shape({
name: yup
.string()
.required('Please, provide your name!'),
password: yup
.string()
.min(4)
.max(10, 'Password should not excced 10 chars.')
.required(),
})}
>
{({ values, handleChange, errors, setFieldTouched, touched, isValid, handleSubmit }) => (
<ScrollView style={styles.scrollb}>
<View style={styles.container}>
<Text style={styles.title}>LOGIN PAGE</Text>
<Text style={styles.subtitle}>Welcome Back.</Text>
</View>
<View style={styles.container2}>
<TextInput
style={styles.tinput}
placeholder="Username"
value={values.name}
onChangeText={handleChange('name')}
onBlur={() => setFieldTouched('name')}
/>
{touched.name && errors.name &&
<Text style={{ fontSize: 12, color: '#FF0D10' }}>{errors.name}</Text>
}
</View>
<View style={styles.container2}>
<TextInput
style={styles.tinput}
placeholder="Password"
value={values.password}
onChangeText={handleChange('password')}
placeholder="Password"
onBlur={() => setFieldTouched('password')}
secureTextEntry={true}
/>
{touched.password && errors.password &&
<Text style={{ fontSize: 12, color: '#FF0D10' }}>{errors.password}</Text>
}
</View>
<View style={styles.container3}>
<TouchableHighlight
style={{
borderRadius: 10,
}}>
<Button
title="Login"
borderRadius={25}
containerViewStyle={{ borderRadius: 25 }}
buttonStyle={{ width: 145, height: 45, borderRadius: 25 }}
accessibilityLabel="Learn more about this button"
onPress={() => handleLogin(values.name)}
disabled={!isValid}
/>
</TouchableHighlight>
</View>
</ScrollView>
)}
</Formik>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 24,
backgroundColor: "#61dafb",
},
container2: {
flex: 1,
paddingTop: 14,
paddingHorizontal: 24,
backgroundColor: "#61dafb",
},
container3: {
flex: 1,
paddingTop: 284,
paddingHorizontal: 34,
backgroundColor: "#61dafb",
borderRadius: 40,
},
title: {
marginTop: 16,
borderRadius: 6,
backgroundColor: "#61dafb",
color: "white",
textAlign: "center",
fontSize: 50,
fontWeight: "bold",
},
subtitle: {
borderRadius: 6,
paddingLeft: 33,
backgroundColor: "#61dafb",
color: "white",
textAlign: "left",
fontSize: 30,
fontWeight: '400',
},
tinput: {
height: 50,
textAlign: "center",
paddingVertical: 8,
backgroundColor: "white",
borderRadius: 27,
},
scrollb: {
backgroundColor: "#61dafb",
},
});
export default Login;
This is my Home screen file. Where I want to retrieve that username from Login Page via async storage.
import React, { Component, useEffect, useState } from 'react';
import { View, Text, ScrollView, TouchableHighlight, Image, StyleSheet } from 'react-native';
import { getData } from '../utils/storage';
const Home = (props) => {
const [username, setUsername] = useState('');
useEffect(() => {
getData('username')
console.log('useEffect',getData('username'))
}, [])
const CategoriesAr = [
{
name: "Business",
path: "Business",
imgURL: "https://img.icons8.com/clouds/100/000000/analytics.png",
},
{
name: "Technology",
path: "Technology",
imgURL: "https://img.icons8.com/clouds/100/000000/transaction-list.png",
},
{
name: "Science",
path: "Science",
imgURL: "https://img.icons8.com/clouds/100/000000/innovation.png",
},
{
name: "Health",
path: "Health",
imgURL: "https://img.icons8.com/clouds/100/000000/client-company.png",
}
]
const GridItem = (gridProps) => {
const { data } = gridProps;
return (
<>
<TouchableHighlight onPress={() => props.navigation.navigate(data.path)}>
<View style={styles.card}>
<View style={styles.header}>
<Text style={{ fontWeight: "bold", fontSize: 18 }}>{data.name}</Text>
</View>
<View style={styles.imgbody}>
<Image
style={styles.tinyLogo}
source={{
uri: data.imgURL,
}}
/>
</View>
</View>
</TouchableHighlight>
</>
)
}
return (
<ScrollView style={styles.sclb}>
<Text style={styles.title}>Hi {username}</Text>
<View style={styles.containerX}>
{CategoriesAr.map((item) => <GridItem data={item} />)}
</View>
</ScrollView>
);
}
const styles = StyleSheet.create({
title: {
marginTop: 16,
borderRadius: 6,
backgroundColor: "#61dafb",
color: "white",
textAlign: "center",
fontSize: 50,
fontWeight: "bold",
},
containerX: {
flex: 1,
flexWrap: "wrap",
marginTop: 8,
maxHeight: 400,
backgroundColor: "#61dafb",
},
card: {
height: 150,
width: 150,
backgroundColor: "white",
alignItems: "center",
borderRadius: 15,
elevation: 10,
padding: 10,
margin: 22,
},
imgbody: {
paddingTop: 20,
},
tinyLogo: {
height: 90,
width: 90,
},
header: {
flexDirection: "row",
},
sclb: {
backgroundColor: "#61dafb",
}
});
export default Home;
You need to put await before getData like this.
useEffect(() => {
(async()=>{
await getData('username')
console.log('useEffect',await getData('username'))
})();
}, [])
useEffect(() => {
CallMethod()
}, [])
const CallMethod = async() =>{
await getData('username')
}
I would like to display selected items, but the situation I have got is not showing images but only the backgroundColor. There is image uri in productData, so I would like to display the uri. Another issue I am having is that the CheckBox is not checked.
My code below :
const styles = StyleSheet.create({
container: {
flex: 1,
marginTop: 100,
},
topContainer: {
flexDirection: 'row',
marginHorizontal: 15,
paddingBottom: 20,
paddingTop: 10,
borderBottomWidth: 0.5,
borderColor: colors.very_light_pink,
},
iconWrap: {
width: 60,
height: 60,
borderRadius: 6,
backgroundColor: '#cccccc',
alignItems: 'center',
justifyContent: 'center',
marginRight: 5,
},
icon: {
width: 20,
height: 20,
},
row: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
marginHorizontal: 15,
marginBottom: 15,
},
});
const productData = [
{
id: 0,
productName: 'a',
price: 45000,
image:
'https://static.zara.net/photos///2021/V/0/2/p/8211/407/250/73/w/563/8211407250_2_1_1.jpg?ts=1613387641299',
},
{
id: 1,
productName: 'b',
price: 45000,
image:
'https://static.zara.net/photos///2021/V/0/2/p/0526/407/707/2/w/1280/0526407707_6_1_1.jpg?ts=1610451943259',
},
{
id: 2,
productName: 'c',
price: 129000,
image:
'https://static.zara.net/photos///2021/V/0/2/p/0706/442/710/2/w/563/0706442710_2_1_1.jpg?ts=1614254205907',
},
{
id: 3,
productName: 'd',
price: 139000,
image:
'https://static.zara.net/photos///2021/V/0/2/p/0706/431/446/2/w/563/0706431446_2_1_1.jpg?ts=1613386951068',
},
{
id: 4,
productName: 'e',
price: 189000,
image:
'https://static.zara.net/photos///2021/V/0/2/p/4162/536/401/2/w/1280/4162536401_1_1_1.jpg?ts=1613122054256',
},
{
id: 5,
productName: 'f',
price: 89000,
image:
'https://static.zara.net/photos///2021/V/0/2/p/4165/537/430/2/w/563/4165537430_1_1_1.jpg?ts=1613122064808',
},
];
const LiveAddProducts = (props) => {
const [productClicked, setProductClicked] = useState(null);
const [selectedProducts, setSelectedProducts] = useState([]);
useEffect(() => {
if (productClicked !== null) {
setSelectedProducts((prevState) => [
...prevState,
// I believe this should be changed
{ id: prevState.length, image: productClicked },
]);
setProductClicked(null);
}
}, [productClicked]);
console.log(selectedProducts.image);
return (
<View style={[styles.container]}>
<View style={[styles.topContainer]}>
<TouchableOpacity style={[styles.iconWrap]}>
<Image source={assets.live_add_icon} style={[styles.icon]} />
</TouchableOpacity>
{selectedProducts.map((item, index) => (
<TouchableOpacity style={[styles.iconWrap]} key={item.id}>
<Image source={{ uri: productData.image }} style={[styles.icon]} />
</TouchableOpacity>
))}
</View>
<ScrollView style={{ paddingTop: 20 }}>
{productData.map((item, index) => (
<View style={[styles.row]}>
<ProductsList
price={item.price}
image={item.image}
productName={item.productName}
/>
// Any problems here?
<CheckBox
size={20}
onPress={() => setProductClicked(index)}
source={
productClicked === index
? assets.icon_check_on
: assets.checked_off
}
/>
</View>
))}
</ScrollView>
<BottomButton
btnText={'Add Items'}
buttonStyle={{ height: 50, backgroundColor: colors.iris }}
/>
</View>
);
};
LiveAddProducts.propTypes = {};
export default LiveAddProducts;
The image which has problems :
useEffect(() => {
if (productClicked !== null) {
setSelectedProducts((prevState) => [
...prevState,
// I believe this should be changed
{ id: prevState.length, image: productClicked },
]);
setProductClicked(null);
}
}, [productClicked]);
Here, you'd want to replace this with the index of the element
id: prevState.length
Also,
{selectedProducts.map((item, index) => (
<TouchableOpacity style={[styles.iconWrap]} key={item.id}>
<Image source={{ uri: productData.image }} style={[styles.icon]} />
</TouchableOpacity>
))}
Here, the uri should be item.image, as that is where you hold the data for your item when it is rendered in this loop