If, if else, else doesn't work in cypress - conditional-statements

I have the following code, but block with else if doesn't work,
how can I change this code, to make the if else block work?
cy.get('#cards-list').then((list) => {
const valueFormList = list.find(`a:contains('${nameForSite}')`)
const nextArrow = list.find(`li.pagination-next`)
if (valueFormList.length > 0 && nextArrow.length > 0){
cy.get(`a:contains('${nameForSite}')`).as('card')
} else if (valueFormList.length < 0 && nextArrow.length > 0) {
cy.get('li.pagination-next').click()
cy.wait(200)
cy.findCardOnFacebook(nameForSite)
} else {
cy.get('h4.learning-opportunities-title').should('contain', 'Learning')
}
})

The error is because of the condition valueFormList.length < 0. The length can never be less than 0. Either it can be zero or more than zero.
cy.get('#cards-list').then((list) => {
const valueFormList = list.find(`a:contains('${nameForSite}')`)
const nextArrow = list.find(`li.pagination-next`)
if (valueFormList.length == 0 && nextArrow.length > 0) {
cy.get('li.pagination-next').click()
cy.wait(200)
cy.findCardOnFacebook(nameForSite)
} else if (valueFormList.length > 0 && nextArrow.length > 0) {
cy.get(`a:contains('${nameForSite}')`).as('card')
} else {
cy.get('h4.learning-opportunities-title').should('contain', 'Learning')
}
})

Related

TypeError: Cannot read properties of undefined (reading 'type') at eval ... at Array.sort (<anonymous>)

I need your help with this error I am facing colleagues. I am new to vue so I am finding it quite difficult to solve the error though I what what exactly is causing the error. I am creating a datatable in vue and I am trying to achieve data sorting with this tutorial I am following but end up getting the following error:
TypeError: Cannot read properties of undefined (reading 'type')
computed: {
filteredAccommodations(){
let accommodations = this.accommodations;
if (this.search) {
accommodations = accommodations.filter((row) => {
return Object.keys(row).some((key) => {
return String(row[key]).toLowerCase().indexOf(this.search.toLowerCase()) > -1;
})
});
}
let sortKey = this.sortKey;
let order = this.sortOrders[sortKey] || 1;
if(sortKey){
accommodations = accommodations.slice().sort((a, b) => {
let index = this.getIndex(this.columns, 'name', sortKey);
a = String(a[sortKey]).toLowerCase();
b = String(b[sortKey]).toLowerCase();
if (this.columns[index].type && this.columns[index].type === 'date') {
return (a === b ? 0 : new Date(a).getTime() > new Date(b).getTime() ? 1 : -1) * order;
} else if (this.columns[index].type && this.columns[index].type === 'number') {
return (+a === +b ? 0 : +a > +b ? 1 : -1) * order;
} else {
return (a === b ? 0 : a > b ? 1 : -1) * order;
}
});
}
return accommodations;
},
paginatedAccommodations(){
return this.paginate(this.filteredAccommodations, this.length, this.pagination.currentPage);
}
},
The reason for your error is because the value of this.columns[index] is a null value ,Adding a null check in ur if loop might help you solve this but I suggest you to check for the reason of null value.
computed: {
filteredAccommodations() {
let accommodations = this.accommodations;
if (this.search) {
accommodations = accommodations.filter((row) => {
return Object.keys(row).some((key) => {
return String(row[key]).toLowerCase().indexOf(this.search.toLowerCase()) > -1;
})
});
}
let sortKey = this.sortKey;
let order = this.sortOrders[sortKey] || 1;
if (sortKey) {
accommodations = accommodations.slice().sort((a, b) => {
let index = this.getIndex(this.columns, 'name', sortKey);
a = String(a[sortKey]).toLowerCase();
b = String(b[sortKey]).toLowerCase();
if (this.columns[index] && this.columns[index].type && this.columns[index].type === 'date') {
return (a === b ? 0 : new Date(a).getTime() > new Date(b).getTime() ? 1 : -1) * order;
} else if (this.columns[index] && this.columns[index].type && this.columns[index].type === 'number') {
return (+a === +b ? 0 : +a > +b ? 1 : -1) * order;
} else {
return (a === b ? 0 : a > b ? 1 : -1) * order;
}
});
}
return accommodations;
},
paginatedAccommodations() {
return this.paginate(this.filteredAccommodations, this.length, this.pagination.currentPage);
}
},

React native run useState/force rerender inside worklet funtion

I'm calling the useAnimatedScrollHandler hook from react-native-reanimated to handle my onScroll function on an Animated.ScrollView. This hook works as expected but I now want to disable a custom button (My FlatButton) based on the currentIndex which is a sharedValue. But when the sharedValue changes the screen doesn't get rerendered, because the state doesn't change so the look of my button remains the same.
Is there a way to force a rerender inside of a worklet, or is it possible to use useState to force a rerender from inside a worklet?
const scrollHandler = useAnimatedScrollHandler((event) => {
translationX.value = event.contentOffset.x
if (event.contentOffset.x < width * 0.5 && currentIndex.value != 0) {
currentIndex.value = 0
} else if (
event.contentOffset.x > width * 0.5 &&
event.contentOffset.x < width * 1.5 &&
currentIndex.value != 1
) {
currentIndex.value = 1
} else if (event.contentOffset.x > width * 1.5 && currentIndex.value != 2) {
currentIndex.value = 2
}
})
<FlatButton
label="Next"
disabled={
(currentIndex.value == 0 && (!firstName || !lastName)) ||
(currentIndex.value == 1 && (!dateOfBirth || !sex)) ||
(currentIndex.value == 2 &&
(!streetNumber || !postalCode || !city || !state || !country))
}
onPress={() => {
if (currentIndex.value == 0) {
scrollRef.current
?.getNode()
.scrollTo({ x: width, animated: true })
} else if (currentIndex.value == 1) {
scrollRef.current?.getNode().scrollToEnd({ animated: true })
}
}}
/>
I just found out that reanimated offers the function runOnJS which makes it possible to run a javscript function like setState inside a worklet. So just create a wrapper function, like in my case toggleIndex in which you interact with your state and call this function inside runOnJS from your worklet.
const [currentIndex, setCurrentIndex] = useState(0)
const toggleIndex = (index: number) => {
setCurrentIndex(index)
}
const scrollHandler = useAnimatedScrollHandler((event) => {
translationX.value = event.contentOffset.x
if (event.contentOffset.x < width * 0.5 && currentIndex != 0) {
runOnJS(toggleIndex)(0)
} else if (
event.contentOffset.x > width * 0.5 &&
event.contentOffset.x < width * 1.5 &&
currentIndex != 1
) {
runOnJS(toggleIndex)(1)
} else if (event.contentOffset.x > width * 1.5 && currentIndex != 2) {
runOnJS(toggleIndex)(2)
}
})

vue.js function only working if value is greater than zero

I have the following function that is formating font colour based on the value returned. The value returned is from a GraphQl non-nullable field and is in a range from 0-10. It works perfectly if the value is 1-10, if the value is zero it does not run as expected.
formatFont: function (state) {
if (state) {
if (state >= 0 && state <= 6) {
return 'red--text';
} else if (state >= 7 && state <= 8) {
return 'orange--text';
} else if (state >= 9 && state <= 10) {
return 'green--text';
} else {
return 'white-text' // i.e. white on white = invisible
}
} else {
console.log('Output else')
return 'white--text' // i.e. white on white = invisible
}
}
If the value is zero it will return the else statement, I have a solution to increment each value by 1 which resolves but it feels like a hack, I want to understand why it doesn't recognise zero?
change
if (state) {
to
if (typeof state !== 'undefined') {
why because 0 is falsey
var a= 0
var b= '0'
var c= 1
if(a) {
console.info('a',a)
}
if(b){
console.info('b',b)
}
if(c){
console.info('c',c)
}
Because of the 0 as a false consider but you pass as a string then it will go the true.

How can I make this code work for expiry date TextInput which includes (mm/yy) model?

I want to create a checkout form which includes expiry date TextInput. It will look like a this (MM/YY). After adding first 2 digits it will automatically add / then the person can type last 2 digits for the year. I found this code on the other question. But it doesn't work. When you type inside the form nothing is typed. Here is the code. How can I make this code work as needed?
constructor() {
super()
this.state = {
isReady: false
}
}
componentDidMount() {
this.setState({
isReady: true
})
}
onChange(text) {
let newText = '';
let numbers = '0123456789';
for (var i = 0; i < text.length; i++) {
if ( numbers.indexOf(text[i]) > -1 ) {
newText = newText + text[i];
}
}
this.setState({myNumber: newText})
}
formatFunction(cardExpiry = ""){
//expiryDate will be in the format MMYY, so don't make it smart just format according to these requirements, if the input has less than 2 character return it otherwise append `/` character between 2nd and 3rd letter of the input.
if(cardExpiry.length < 2){
return cardExpiry;
}
else{
return cardExpiry.substr(0, 2) + "/" + (cardExpiry.substr(2) || "")
}
}
inputToValue(inputText){
//if the input has more than 5 characters don't set the state
if(inputText.length < 6){
const tokens = inputText.split("/");
// don't set the state if there is more than one "/" character in the given input
if(tokens.length < 3){
const month = Number(tokens[1]);
const year = Number(tokens[2]);
//don't set the state if the first two letter is not a valid month
if(month >= 1 && month <= 12){
let cardExpiry = month + "";
//I used lodash for padding the month and year with zero
if(month > 1 || tokens.length === 2){
// user entered 2 for the month so pad it automatically or entered "1/" convert it to 01 automatically
cardExpiry = _.padStart(month, 2, "0");
}
//disregard changes for invalid years
if(year > 1 && year <= 99){
cardExpiry += year;
}
this.setState({cardExpiry});
}
}
}
}
render (){
let {cardExpiry} = this.state;
return (
<Image style={styles.image} source={require('../img/cover.jpg')}
>
<Content style={styles.content}>
<Form>
<Item >
<Icon active name='card'/>
<Input keyboardType='numeric' maxLength={16} placeholder='Card Number'
onChangeText = {(text)=> this.onChange(text)}
value = {this.state.myNumber}/>
</Item>
<Grid>
<Row>
<Col>
<Item style={{ marginBottom:10}}>
<Icon active name='calendar' />
<Input keyboardType='numeric' placeholder='MM/YY'
value = {this.formatFunction(cardExpiry)}
onChangeText={this.inputToValue.bind(this)}/>
</Item>
</Col>
<Col>
<Item style={{ marginBottom:10}}>
<Icon active name='lock' />
<Input maxLength={3} secureTextEntry={true} placeholder='CVV'/>
</Item>
</Col>
</Row>
</Grid>
Use this code to handle your problem:
constructor(props) {
super(props);
this.state = { text: '' };
}
handleChange = (text) => {
let textTemp = text;
if (textTemp[0] !== '1' && textTemp[0] !== '0') {
textTemp = '';
}
if (textTemp.length === 2) {
if (parseInt(textTemp.substring(0, 2)) > 12 || parseInt(textTemp.substring(0, 2)) == 0) {
textTemp = textTemp[0];
} else if (this.state.text.length === 2) {
textTemp += '/';
} else {
textTemp = textTemp[0];
}
}
this.setState({text: textTemp})
}
render() {
return (
<TextInput
keyboardType={'numeric'}
onChangeText={this.handleChange}
value={this.state.text}
maxLength={5}
/>
);
}
After searching a lot for Picker with Month/Year, for the time being i have created a logic for the Expiry date.
Hope this will help somebody.
const onCardExpiryDateChange = (prevValue:string, currentValue: string) => {
if (currentValue?.includes(',') || currentValue?.includes('-') || currentValue?.includes('.')) {
return prevValue
} else {
let textTemp = currentValue
if (textTemp[0] !== '0' && textTemp[0] !== '1' && textTemp[0] !== '2' && textTemp[0] !== '3') {
textTemp = '';
} else if ((prevValue?.length === 5) && currentValue.length === prevValue.length-1) {
textTemp = textTemp?.slice(0, -3)
} else if (textTemp.length === 6 && (textTemp[5] == '0' || textTemp[5] == '1')){
textTemp = textTemp?.slice(0, -1)
}
else if (textTemp.length === 7 && textTemp[6] == '0') {
textTemp = textTemp?.slice(0, -1)
} else if (textTemp.length === 2) {
if (parseInt(textTemp?.substring(0, 2)) > 12 || parseInt(textTemp?.substring(0, 2)) == 0) {
textTemp = textTemp?.slice(0, -1)
} else if (textTemp?.length === 2) {
textTemp += ' / ';
} else {
textTemp = textTemp[0];
}
}
return textTemp
}
}
As #AndroConsis pointed out in #Vahid Boreiri's answer, the only problem with adding '/' after length 2 is when deleting the expiry date it keeps adding '/'. To fix this, one can add a conditional backspaceFlag.
const [backspaceFlag, setBackspaceFlag] = React.useState(false);
const [expiratoinDate, setExpirationDate] = React.useState('');
const handleExpirationDate = (text) => {
let textTemp = text;
if (textTemp[0] !== '1' && textTemp[0] !== '0') {
textTemp = '';
}
if (textTemp.length === 2) {
if (parseInt(textTemp.substring(0, 2)) > 12 || parseInt(textTemp.substring(0, 2)) == 0) {
textTemp = textTemp[0];
} else if (text.length === 2 && !backspaceFlag) {
textTemp += '/';
setBackspaceFlag(true);
} else if (text.length === 2 && backspaceFlag) {
textTemp = textTemp[0];
setBackspaceFlag(false);
} else {
textTemp = textTemp[0];
}
}
setExpirationDate(textTemp);
};
const [expiratoinDate, setExpirationDate] = useState(''); const [backspaceFlag, setBackspaceFlag] = useState(false);
const handleExpirationDate = (text) => {
if(backspaceFlag===false){
if(text.length==2){ setExpirationDate(text+"/"); setBackspaceFlag(true) }
`else{
setExpirationDate(text)
}`
}
else{
if(text.length==2){
let text2=expiratoinDate.slice(0,1)
`setExpirationDate(text2);`
`setBackspaceFlag(false)
}`
`else{
setExpirationDate(text)
}`
}
`};`
Adding an answer that resolves not being able to delete the '/' in above solution.
const setExpiry = (e) => {
const { name, value } = e.target;
var v = value;
if (v.includes('/') == false) {
if (v.length === 4) {
var a = v.substr(0, 2);
var ae = v.charAt(v.length - 2) + v.charAt(v.length - 1);
e.target.value = a + '/' + ae;
}
}
}

How to check is two lines intersect/overlap on a grid?

This is a rather trivial algorithmic problem but my implementation leaves speed and simplicity to be desired. I've got two Line objects which each hold two Coordinate structs in the form of {unsigned int x, unsigned int y}. This first Coordinate holds the position of the beginning of the line and the second Coordinate, the end of it. Assuming that Lines can only be vertical or horizontal on the grid, how can I check when two lines overlap parallelly or intersect perpendicularly. Preferably this is implemented as a method in Line:
- (BOOL)intersectsLine:(Line)otherLine;
THANKS!
Since we're talking only about horizontal or vertical lines, the first step I'd take it checking whether or not the lines have the same orientation.
typedef (NSUInteger, LineOrientation) {
HorizontalLine = 0,
VerticalLine = 1
};
So, given a line with two points...
LineOrientation line1orientation;
LineOrientation line2orientation;
if (a.x1 == a.x2) {
line1orientation = HorizontalLine;
} else {
line1orientation = VerticalLine;
}
if (b.x1 == b.x2) {
line2orientation = VerticalLine;
} else {
line2orientation = Horizontal;
}
Now we need to check whether they're both horizontal, both vertical, or one of each, and then test particular values:
if (line1orientation == line2orientation) {
if (line1orientation == VerticalLine) {
if (a.x1 != b.x1) {
return false;
} else {
if (a.y1 < a.y2) {
return ((b.y1 > a.y1 && b.y1 < a.y2) ||
(b.y2 > a.y1 && b.y2 < a.y2));
} else {
return ((b.y1 > a.y2 && b.y1 < a.y1) ||
(b.y2 > a.y2 && b.y2 < a.y1));
}
}
} else {
if (a.y1 != b.y1) {
return false;
} else {
if (a.x1 < a.x2) {
return ((b.x1 > a.x1 && b.x1 < a.x2) ||
(b.x2 > a.x1 && b.x2 < a.x2));
} else {
return ((b.x1 > a.x2 && b.x1 < a.x1) ||
(b.x2 > a.x2 && b.x2 < a.x1));
}
}
}
} else {
if (line1orientation == VerticalLine) {
if (a.y1 < a.y2) {
return (((b.y1 > a.y1) && (b.y1 < a.y2)) && ((b.x1 > a.x1 && b.x2
< a.x1) || (b.x2 > a.x1 && b.x1 < a.x1)));
} else {
return (((b.y1 > a.y2) && (b.y1 < a.y1)) && ((b.x1 > a.x1 && b.x2
< a.x1) || (b.x2 > a.x1 && b.x1 < a.x1)))
}
} else {
if (a.x1 < a.x2) {
return (((b.x1 > a.x1) && (b.x1 < a.x2)) && ((b.y1 > a.y1 && b.y2
< a.y2) || (b.y2 > a.y1 && b.y1 < a.y1)));
} else {
return (((b.x1 > a.x2) && (b.x1 < a.x1)) && ((b.y1 > a.y1 && b.y2
< a.y2) || (b.y2 > a.y1 && b.y1 < a.y1)));
}
}
This could be more efficient if you start with a check to make sure the lines aren't the same line.