Check if value is undefined before render React Native - javascript

I am using (Drop Down Picker library) to display categories of my data which I get from api call. I am waiting for api to fetch the data and then plan to display the categories. The problem is that I need to reformat data first and use hooks before render, but I can't get it right.
how does the data for picker looks like:
items={[
{label: 'USA', value: 'usa'},
{label: 'UK', value: 'uk'},
{label: 'France', value: 'france'/>},
]}
my hooks:
const [country, setCountry] = useState("0");
const [categoryData, setCategoryData] = useState();
const [testingCategories, setTestingCategories] = useState({
label: null,
value: null,
});
my effect hooks and reformatting the data:
//this hook calls api and sets the data to categories data of my type
useEffect(() => {
getData(api.API_GET_DEPS, setIsLoading, setCategoryData);
}, []);
//this hooks reformats the data into acceptable format for picker
useEffect(() => {
setTestingCategories(
categoryData
? categoryData.map((item) => ({
label: item.DEPNAME, //label
value: item.DEPID, //value
}))
: [{ label: null, value: null }]
);
}, [categoryData]);
my render of drop down:
<View style={styles.container}>
{testingCategories ? (
<DropDownPicker
dropDownMaxHeight={300}
placeholder="All"
defaultValue={country}
items={testingCategories}
containerStyle={{ height: 50 }}
style={{ backgroundColor: "#fafafa" }}
itemStyle={{
justifyContent: "flex-start",
}}
dropDownStyle={{ backgroundColor: "#fafafa" }}
onChangeItem={(item) => {
console.log("changed");
}}
onOpen={() => setContainerOpacity(0.1)}
onClose={() => setContainerOpacity(1)}
labelStyle={{
fontSize: 16,
color: colors.dark,
fontWeight: "600",
}}
arrowSize={25}
arrowColor={colors.dark}
/>
) : (
<></>
)}
I get an error that drop down picker can't match the defaultValue with any label in testingCategories because it is null and haven't loaded yet. I suppose I am using setter wrong because I can't check whether testingCategories's first element was loaded. What am I doing wrong?

You have a typing mismatch between your useState definition and where you use setTestingCategories later.
In your useState, you define the initial value as a singular object:
useState({
label: null,
value: null,
});
However, what you probably want is an empty array:
useState([]);
I would also change your current line [{ label: null, value: null }] to just be an empty array [].
Then, your testingCategories flag will work, because testingCategories will initially be an array of length 0, which will fail the truthiness test.

Related

Error in the values of the Rechart Stacked chart

I'm trying to build a Stacked Bar Chart using the Pchart library. I attach the code below.
function StackedBarChart({...props}){
const {dataChart:{data,keys}} = props;
const renderBars = () =>{
return keys.map((item,index)=>(
<Bar
key={index}
dataKey={item}
stackId='a'
fill={index%2?'blue':'red'}
label
/>
))
}
return(
<ResponsiveContainer width='100%' height={400}>
<BarChart
data={data}
stackOffset='expand'
>
<XAxis dataKey="name" />
<YAxis />
{renderBars()}
</BarChart>
</ResponsiveContainer>
)
}
When I output a value to each Bar I get incorrect signatures. . Why is 2 Bar subscribed with the value 1 and not the remaining percentage. What is my mistake ?
my data
const dataChart = {
data: [{
name: 'Page A',
count: 4000,
price: 2400,
},
{
name: 'Page B',
count: 3000,
price: 1398,
},
{
name: 'Page C',
count: 2000,
price: 9800,
},
],
keys: ['price', 'count']
};
The reason of this behavior, is that upper bar shown his top value, which is 1, so this is the sum of all bars stacked.
To avoid this situation I used valueAccessor and some formatting to get value of bar and count its percentage.
Here is a link to working codesandbox where you can see final result

How to Solve ERROR Warning: Failed prop type: Invalid prop `style` of type `array` supplied to `Row`, expected `object` (react-native-table-component)

Here i'm working on a react-native-table-compornent.
when i try to run my project, and display my data in table (react native),
i get this type of error ( ERROR Warning: Failed prop type: Invalid prop textStyle of type array supplied to Cell, expected object.) on my project;
how can solve this error warning?
where is the problem in my codes? i am sharing here in below my codes.
when i excute this code, i can able to view those data in table but besides i also get this error warning in my project, so i want to solve this Warning.
anyone can help me how to fix this error or where i should do what in my project?
i appreciate your helping, thankyou in advance!
Here i am sharing my codes, i have use in vs code(react native):
import React from "react";
import { StyleSheet, View, ScrollView } from "react-native";
import { Table, Row } from "react-native-table-component";
const TT = () => {
const th = ["Name", "Age", "Gmail", "Occupation"];
const widthArr = [150, 150, 150, 150];
const td = [
["John", 32, "john01#gmail.com", "Doctor"],
["Paul", 39, "poul09#gmail.com", "Teacher"],
["Rokey", 45, "rokey03#gmail.com", "Engineer"]
];
return (
<View style={styles.container}>
<ScrollView horizontal={true}>
<View>
<Table
style={{ marginTop: 12, marginLeft: 12 }}
borderStyle={{ borderColor: "#FAEBD7", borderWidth: 1 }}
>
<Row
data={th}
widthArr={widthArr}
style={styles.header}
textStyle={styles.headerText}
/>
</Table>
<ScrollView style={styles.dataWrapper}>
<Table
style={{ marginLeft: 12 }}
borderStyle={{ borderColor: "#FAEBD7", borderWidth: 1 }}
>
{td?.map((rowData, index) => (
<Row
key={index}
data={rowData}
widthArr={widthArr}
style={[
styles.row,
index % 2 && { backgroundColor: "#212733" }
]}
textStyle={styles.text}
/>
))}
</Table>
</ScrollView>
</View>
</ScrollView>
</View>
);
};
export default TT;
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: 20,
paddingBottom: 18,
backgroundColor: "#212732"
},
header: {
height: 50,
backgroundColor: "#2F4F4F"
},
headerText: {
textAlign: "center",
fontWeight: "400",
color: "white"
},
text: {
textAlign: "center",
fontWeight: "300",
color: "#fefefe"
},
dataWrapper: {
marginTop: -1
},
row: {
height: 40,
backgroundColor: "#2c3445"
}
});
output of error:
react-native-table-component isn't being maintained by its original developer. Warnings like this are covered in the repo's issues section, and there are great forks that fix some errors.
So in my case i choose to use different library which is react native paper;
libraries: npm i react-native-paper
using dataTable i finished my project. for more information https://callstack.github.io/react-native-paper/data-table.html

How do I mutate Chart.js data using React state?

In my project I wish to toggle between two sets of data: total hours worked each day in current week, and total hours worked each month in the current year. I am able to achieve Chart.js label manipulation in my button handlers, but I am unable to modify the state's data property. What am I missing here? Thank you for helping.
Note: The commented code produce this error statement when uncommented:
Uncaught TypeError: nextDatasets.map is not a function
LineChart.js
const [userData, setUserData] = useState({
labels: Object.keys(daysData),
datasets: [
{
label: "Hours worked",
data: Object.values(daysData),
backgroundColor: "red",
borderColor: "black",
borderWidth: 2,
},
],
});
const onShowWeeklyHandler = () => {
setUserData({ labels: Object.keys(daysData) });
// setUserData({ datasets: { data: Object.keys(daysData) } });
};
const onShowMonthlyHandler = () => {
setUserData({ labels: Object.keys(monthsData) });
// setUserData({ datasets: { data: Object.keys(monthsData) } });
};
You may be encountering issues because you are trying to shallow merge state with the useState hook. React does not support this. See this answer for more info.
If that does not solve your issue, have you looked into react-chartjs-2? You might be able to achieve what you want doing something like the following.
In your parent component (the one that contains the chart):
import { Bar } from "react-chartjs-2"; // import whatever chart type you need
...
const [userData, setUserData] = useState({
labels: Object.keys(daysData),
datasets: [
{
label: "Hours worked",
data: Object.values(daysData),
backgroundColor: "red",
borderColor: "black",
borderWidth: 2,
},
],
});
Then your handlers can be:
const onShowWeeklyHandler = () => {
setUserData({
...userData,
datasets: {
...userData.datasets,
labels: Object.keys(daysData),
data: Object.values(daysData),
},
});
};
const onShowMonthlyHandler = () => {
setUserData({
...userData,
datasets: {
...userData.datasets,
labels: Object.keys(monthsData),
data: Object.values(monthsData),
},
});
};
Finally:
return <Bar data={userData.datasets} />; // adapt for whatever chart type you need

general questions regarding react native. props and style

I was tasked with making some tweaks on a react native app. while it's not my skill there is no one available to work on this so I am stuck with it. for the most part I was able to make the edits needed, however I have few questions about the code if anyone can help me understand better.
1 - what is the difference between
color={Colors.myColorGold}
color: Colors.myColorGold
2 - if I want to use the predefined style but change one parameter like color, or font size how can I do it while keeping the rest of the parameters
<Text style={{ color: Colors.ochsnerGold, fontWeight: 'bold' }}>
<Text style={styles.emphasized}>{alert.SensorType}</Text>
3 -
what is the differance between the two below
this.props.navigation.navigate('NotificationPreferences');
this.navigate('NotificationPreferences')
4 - and lastly, I wanted to change the color of the placeholder, I have tried everything without success, below is the code and all the things I tried.
const ItemPicker = ({itemOptions, handleChangeitem, selectedItemID}) => {
return Platform.OS === 'ios' ? (
<RNPickerSelect
placeholder={{label: 'Select an item', value: null, placeholderTextColor: Colors.myGold}}
placeholderTextColor={Colors.myGold} //tried this
items={itemOptions}
onValueChange={handleChangeItem}
style={{inputIOS: styles.inputIOS, inputAndroid: styles.inputAndroid, Color: Colors.myGold}} //tried this
value={selectedItemID}
textColor={Colors.myGold} //tried this
/>
) : (
<Picker
selectedValue={selectedItemID}
style={styles.inputAndroid}
onValueChange={handleChangeItem}
textColor={Colors.myGold} //tried this
Color={Colors.myGold} //tried this
>
<Picker.Item label="Select a Item" value="null" textColor={Colors.myGold} Color={Colors.myGold}/> //tried this
{
itemOptions.map((item) => (
<Picker.Item key={item.value} label={item.label} value={item.value} textColor={Colors.myGold} Color={Colors.myGold} /> //tried this
))
}
</Picker>
)
}
For
1. If you are using a component which has style as its props so you can use as color={Colors.myColorGold} . like suppose in
<MaterialIcon color={Colors.myColorGold} />
and if you want to add a color property in the styles object you do :
const proAppHeaderStyles=StyleSheet.create({
hederStyle:{
color:"#4f58ff",
}
})
suppose you want to change in
<Text style={styles.emphasized}> {alert.SensorType}</Text> just go to styles.emphasized object where its defined and add color or fontsize whatever you want to change. e.g
emphasized:{
color:'red'
}
3.this.props.navigation.navigate('NotificationPreferences') is same as the below one. Only that the above one states in explicitly and below syntax will only work if you first destructure navigate. i.e
const {navigate} = this.props.navigation; and after that use navigate as below
this.navigate('NotificationPreferences')
SO you have to apply styles as below
<RNPickerSelect
placeholder={{
label: 'Select a number or add another...',
value: null,
color: 'red',
}}
items={this.state.numbers}
onValueChange={value => {
this.setState({
favNumber: value,
});
}}
style={{
...pickerSelectStyles,
iconContainer: {
top: 20,
right: 10,
},
placeholder: {
color: 'purple',
fontSize: 12,
fontWeight: 'bold',
},
}}
value={this.state.favNumber}
Icon={() => {
return (
<View
style={{
backgroundColor: 'transparent',
borderTopWidth: 10,
borderTopColor: 'gray',
borderRightWidth: 10,
borderRightColor: 'transparent',
borderLeftWidth: 10,
borderLeftColor: 'transparent',
width: 0,
height: 0,
}}
/>
);
}}
/>
so basically inside the style object you need to pass placeholder object and then the style :
style={{
...pickerSelectStyles,
iconContainer: {
top: 20,
right: 10,
},
placeholder: { // this is the part
color: 'purple',
fontSize: 12,
fontWeight: 'bold',
},
}}
Do check out this link : example
ask me for doubts.

How can I add custom props to an Option using React Select?

My goal is to add a tooltip when the user expands the menu and hovers over the items listed. To do this, I need to add data-tip and data-for to the menu items.
The options I'm passing to React Select looks like this:
[
{ value: 1, label: 'Onw' },
{ value: 2, label: 'Two' },]
I'd like to just add the prop info there but I don't think there's a way. Do I need to customize the rendering of each option? Any tips on how to do this would be appreciated. Thanks.
You can simply wrap your custom Option inside a function then assign custom props for it
components={{ Option: (optionProps) => <Option {...optionProps} onEditItem={onEditItem}
onDeleteItem={onDeleteItem} /> }}
react-select seems to be only accepting value and label as props (and possibly other HTML attributes that an <option> accepts), so I did this with the help of a function:
const options = [
{ value: "a", label: "A", tooltip: "yellow" },
{ value: "b", label: "B", tooltip: "orange" },
{ value: "c", label: "C", tooltip: "blue" },
];
function getTooltip(value) {
return options.find(x => x.value === value).tooltip;
}
/* A custom option component as an example */
const Option = (props) => {
return (
<components.Option {...props}>
<div data-tip={getTooltip(props.value)}>
{props.label}
</div>
</components.Option>
);
};
/* Pass the custom component to <Select> */
return (
<Select options={options} components={{ Option }} />
)

Categories

Resources