react native function always returns true - react-native

In my application, I want to disable an icon conditionally. Here is my code.
<View style={styles.controlsContainer}>
<WorkoutProgressControls
videoPaused={this.state.videoPaused}
onPrevious={() => alert("PREVIOUS MOVEMENT")}
onPause={() => this._onPauseVideo()}
onNext={() => this.getNextMovement()}
disableNext={() => 1 === 1 ? false : true}
/>
</View>
When I set disableNext to true or false, it works properly. But when I tried to change it conditionally or using a function, it always gets disabled.
this is my component which set the disableNext prop.
<DisableableIcon
iconStyles={styles.icon}
resizeMode="contain"
source={Next}
height={35}
width={35}
disabled={props.disableNext}
onIconPressed={props.onNext}
/>
What is the issue here? Why does this work when I set disableNext to true and false, but returns true always when I try to set it conditionally?

You're trying to pass a function as a prop, therefore to make it work either don't use a function or invoke it as a function in your component.
...
disableNext={() => 1 === 1 ? false : true}
...
...
disabled={props.disableNext()}
...
OR
...
disableNext={1 === 1 ? false : true}
...
...
disabled={props.disableNext}
...

Related

q-input has value then only Rules will apply

If q-input has value != '' then only i want to apply the Rules like required 8 number maximum. In the below code it gives me the required input error even it's null.
<q-input
filled
name="landline"
label="Landline Phone Number"
v-model="user.landline"
placeholder="Landline Phone Number"
ref="landlinePhoneNumber"
type="number"
:maxlength="8"
:rules="[val => val!='' && val.length > 7 || 'Landline Required 8 digit']"
/>
Try to add prop lazy-rules.
By default, it's set to 'ondemand', which means that validation will be triggered only when the component’s validate() method is manually called or when the wrapper QForm submits itself. More info
You have to return true when the field is null first, then validate only if it's not null. Also, add the prop lazy-rules so that it only validates when the form field loses focus.
Here is how I did it in Vue 3, using composable and TypeScript. The form field component:
<q-input
class="q-mt-md"
filled
v-model="id_number"
label="ID Number "
type="text"
hint="Optional/Leave blank if not available"
lazy-rules
:rules="[(val) => isNumberBlankOrValid(val) || 'Invalid ID Number']"
/>
The method isNumberBlankOrValid called from the field above:
const isNumberBlankOrValid = (val: string) => {
if (val.length === 0) {
return true
}
return isValidNumber(val)
}
The isValidNumber for other fields that must be filled:
const isValidNumber = (val: string) => val && isNumeric(val)
The isNumeric method is a simple regex for validating numbers:
const isNumeric = (value: string) => {
return /^\d+$/.test(value)
}

how to conditionally render styles in react native component?

I have a custom component that provides the rendered list of data when the data is available.
But when the data is not available in the example case below where data=[], I want to apply a different style to it.
return (
<FollowableArticleListTemplate
style={hasData}
title={ title }
data={ [] }
isFollowing={ isFollowing }
onToggleFollow={ id ? () => toggleSourceFollow(id, isFollowing, title) : null }
setListRef={ this.setListRef }
contentType="source"
/>
);
What I'm looking for is something like this:
style={hasData}
i.e if the data.length > 0
use this style for this component: style={hasData}
otherwise use this style component: style={noData}
This is easily achieved by using the ternary operator. First, you have to conditionally use data using state, not by giving its value directly into the component.
return (
<FollowableArticleListTemplate
style={myData.length > 0 ? hasData : noData}
title={ title }
data={myData}//this is your state
isFollowing={ isFollowing }
onToggleFollow={ id ? () => toggleSourceFollow(id, isFollowing, title) : null }
setListRef={ this.setListRef }
contentType="source"
/>
);
```

How to set an array of multiple data as a state

So basically I want to be able to collect all the values from multiple inputs and set that array as a state. Here is what I am currently working with:
this.state.basket.map(b => {
return (
<View>
<InputSpinner
style={styles.spinnerQty}
max={50}
min={1}
step={1}
rounded={false}
showBorder
colorMax={"#2a292d"}
colorMin={"#2a292d"}
value={b.qty}
onChange={num => {
this.setState({ popUpQty: num });
}}
/>
<View style={styles.hrLine}></View>
</View>
);
});
So I am iterating my basket and setting a spinner with a value from axios output. So there are now multiple InputSpinner with multiple values.
My question is, how can I collect all the values of the onChange, and push it to an array which will eventually become a state. Something like QuantityState: [] would be the values of all the InputSpinner. Hope that made sense. Any help is appreciated. Thanks!
PS. InputSpinner is an npm package from here.
Through this code you can dynamically add/update onChange number on it's particular array instance. num key will be added when a particular onChange trigger so at the end you will get its values which placed on it's index and if key not found that means onChange never triggered for that index
state = {
spinnerData : {},
basket: []
}
this.state.basket.map((b, index) => {
return (
<View>
<InputSpinner
style={styles.spinnerQty}
max={50}
min={1}
step={1}
rounded={false}
showBorder
colorMax={"#2a292d"}
colorMin={"#2a292d"}
value={b.qty}
onChange={num => {
const newbasket = [...this.state.basket];
newbasket[index]["num"] = num;
this.setState({ basket:newbasket });
}}
/>
<View style={styles.hrLine}></View>
</View>
);
});

How to query graphQL with variables from React-Native?

I can't find the problem in my code when trying to query with variables from react-native. A simple Hello World! is working.
The render:
render() {
return (
<AppContext.Consumer>
{context => {
const{ userID,employeeID,salonID,currentDay,serviceTime}=context.state
return (
<Query
query={query}
variables={{userID:userID,employeeID:employeeID,salonID:salonID,day:currentDay,serviceTime:serviceTime}}
>
{(response, error) => {
console.log(`response: ${response.data.listOfAppointments}`);
console.log(`EMPL: ${response.data.employeeInfo}`);
console.log(`\helo: ${response.data.hello}`);
return (
<Grid>
<Col>
<MyHeader
navigation={this.props.navigation}
title={context.state.currentDay
.format("DD.MM.YYYY")
.toString()}
/>
{!response.data.listOfAppointments? (
<CircularProgress />
) : (
<ScheduleList data={response.data.listOfAppointments} />
)}
</Col>
</Grid>
);
}}
</Query>
);
}}
</AppContext.Consumer>
);
}
The Query:
const query =gql`
query Query($userID:String!,$employeeID:String!,$salonID:String!,$day:Int!,$serviceTime:Int){
hello
listOfAppointments(
userID: $userID
employeeID: $employeeID
salonID: $salonID
day: $day
serviceTime: $serviceTime
) {
start
end
status
disabled
}
employeeInfo(employeeID: $employeeID
salonID: $salonID){
token
name
ID
notifyWhenCreated
notifyWhenDeleted
salonName
}
}
`;
The schemas and types:
If I delete listOfAppointments,employeeInfo and the part where I declare the variables the hello is working.
Otherwise it's giving me status code: 400
react-native log-android is not throwing anything.
If I try to console.log() the result it's undefined.
Thanks!
A status code of 400 usually means the query itself is invalid. It could be that the query has a syntax error, or is somehow not passing validation. To get the detailed response from the server, you can either 1) observe the actual response from the server in the network tab of your browser or 2) capture the error from the component itself.
<Query /* props */>
({ data, error }) => {
console.log(error)
return null
}
</Query>
Note that we're only dealing with the first parameter in the render props function and just using destructuring to get its data and error properties.
As far as I can tell, your query does not have any syntax errors, so I suspect the issue is that some or all of the variables you are passing in are in fact undefined, which will cause your query to blow up if any of them are marked as non-null inside the query.

React Native adjusting font size of listItem dynamically

Hi as shown in the picture you canno't see the full text however I don't want to decrease the fonsize for all other items.
Only if it they're greater that 16 in length.
Can I return the fontSize in my renderTitleStyle method or can I do in within the ListItem props e.g {infoText.length > 16 ? (fontSize: 12) : (fontSize: 32)} However I don't think this works.
renderTitleStyle = item => {
const infoText = item.location_from + item.location_to;
if (infoText.length > 12) {
// Return fontSize ???
}
console.warn(infoText.length);
};
<ListItem
style={styles.activeUser}
onPress={() => this.toggleModalConfirmTrip(item)}
roundAvatar
subtitle={item.user[0].name}
titleStyle={this.renderTitleStyle(item)}
title={`${item.location_from} to ${item.location_to} `}
....[![Example of text not fitting][1]][1]
You should be able to set styles dynamically by passing an array of styles with a style array element that depends on a state or a conditional.
<Text style={[styles.mainStyles, {fontSize: ((infoText && infoText.length) > 16 ? 12 :32) }]}>
{/*other elements*/}
</Text>
In your specific case i would try passing that condictional as property for ListItem Component.
titleStyle={this._renderItemTitleStyle(item)}
dont forget to create the function.
_renderItemTitleStyle = (item) => {
if (item && Object.keys(item).length) {
const infoText = item.location_from + item.location_to;
return {fontSize: (infoText.length > 16 ? 12 :32)}
}
console.warn("param item has no properties");
}