I have the following post which works and getting expected values. I am only able to enter the if block when the value of resp.count is 1 or above. But I want to be able to get into the if block even when the value of resp.count is 0. In other words I am just checking that the variable exists and has value. I am trying not to use something like the following.
if(resp.count !== undefined){}
Is there a better way to achieve this more elegantly? Thanks.
return post(api, { 'Content-Type': 'multipart/form-data' }, data)
.then((resp) => {
// count minimum value will be 0.
// Able to enter the following IF block only when value of count is 1 or above.
if (resp.count) {
// I want to get in here even if value is 0.
}
})
You can safely check if the resp.count is more than or equal to zero
if (resp.count >= 0) {
}
In an event where the count does not exist, it will not satisfy the condition.
console.log(undefined >= 0)
if (rest.count !== undefined) {} is literally saying "if the count key is defined, run the following code"
I'm not sure how you would write that any more legibly.
The below should do it.
return post(api, { 'Content-Type': 'multipart/form-data' }, data)
.then((resp) => {
// Allow zero and up
if (resp.count >= 0) {
// do something...
}
})
For this to walk you'll need to check against falsy values. I think, you'll want to make sure, that the value is neither null, undefined nor "".
For the first two, you could compare against != null (not !== to catch type conversions). If you want to exclude empty string as well, I would follow SamwellTarly's suggestion and compare >= 0.
Related
I am testing a virtual dropdown list, my code is like this:
while (!cy.contains('.ant-select-item',/^Cypress$/)) {
cy.get('.ant-select-dropdown').trigger('wheel', {deltaX:0,deltaY:100});
}
It keeps wheeling down until finds a specific element. However, this code does not work, when contains does not find the specific element, it fails the test instead of return false.
How to make the while loop work?
You can use jQuery, Cypress.$ instead.
while (!Cypress.$('.ant-select-item:contains('Cypress').length) {
cy.get('.ant-select-dropdown').trigger('wheel', {deltaX:0,deltaY:100});
}
One thing - :contains() will match partially, so this is no good if more than one item has the string.
Long version - Cypress.$('.ant-select-item:contains('Cypress') gets a list of matching elements. If none found, it does not fail but the length of the list is 0. Since 0 is falsy, the loop continues.
The loop idea is only good if the dropdown does actually contain the value somewhere, otherwise it spins forever.
While loops generally don't work with Cypress, it would be safer to use a repeating (recursive) function
function findItem(item, loop = 0) {
if (loop === 10) throw 'Too many attempts'
cy.get('.ant-select-item')
.invoke('text')
.then(textsOfCurrentList => {
if (!textsOfCurrentList.contains(item)) {
// wheel down and try next
cy.get('.ant-select-dropdown').trigger('wheel', {deltaX:0,deltaY:100})
findItem(item, ++loop)
} else {
return
}
})
})
findItem('Cypress')
Or with package cypress-recurse
recurse(
() => cy.get('.ant-select-item').invoke('text'),
(textsOfCurrentList) => {
const found = textsOfCurrentList.contains(item)
if (!found) {
cy.get('.ant-select-dropdown').trigger('wheel', {deltaX:0,deltaY:100})
}
return found // true means finish, false means repeat
},
{
log: true,
limit: 10, // max number of iterations
timeout: 30000, // time limit in ms
},
)
A good background info avoid-while-loops-in-cypress
I'm doing a PWA quiz application using React.js and I've met the following problematic:
I can get questions objects with only one answer, and some with multiple.
In the case there is only one possible answer, I want to force the user to only have one possibility.
To do that, I made the following algorithm:
clickOnChoice = (key) => {
if (this.state && this.state.correctAnswers) {
let newChoices = INITIAL_CHOICES; // {}
if (this.state.multiChoice) {
console.log("this.state.multiChoice:", this.state.multiChoice); // this.state.multiChoice: false ???
newChoices = JSON.parse(JSON.stringify(this.state.choices)); // {answer_b: 1}
}
newChoices[key] = 1 - (newChoices[key] | 0); // {answer_b: 1, answer_a: 1}
this.setState({
choices: newChoices
}, this.updateNextButtonState);
}
}
However the execution seems to ignore the condition if (this.state.multiChoice).
What am I missing?
Maybe I need a cup of coffee... ☕
Anyway, thanks in advance!
It is more than likely you are trying to checking a string of 'false' rather than an actual boolean value.
you can check that the string is the expected boolean if (this.state.multiChoice === 'true') or change the value of the state property to true || false
I came up a weird situation while playing with javascript and react.
async componentDidUpdate(previousProps, previousState) {
console.log(previousState.questionNo,this.state.questionNo);
console.log(!previousState.questionNo === this.state.questionNo)
if (!previousState.questionNo === this.state.questionNo) {
console.log("I'm here")
const index = Math.floor(Math.random() * 12); //12 is hardcoded i need to find sth better later
const resp = await questionsApi.get(`/questions/${index}`);
this.setState({ question: resp.data });
}
}
And when i check in console eventhough values are not equal component did not rendered. And also in console console.log(!previousState.questionNo === this.state.questionNo) awkwardly always provides false.
console output is like below:
1 1 Component.js:16
false Component.js:17
1 2 Component.js:16
false component.js:17
any idea what is going on ?
Thanks
Replace
if (!previousState.questionNo === this.state.questionNo)
by
if (previousState.questionNo !== this.state.questionNo)
This is because doing !previousState.questionNo will convert the value to a boolean (mostly false) which will never be equal to this.state.questionNo as that is a number like 1, 2, etc
I'm getting the below error when I check the length of an array. What would be the correct approach?
main.js
if (drugPrice.mailPrice.rejectMessage.length !== 0 && Array.isArray(drugPrice.mailPrice.rejectMessage)) {
//code goes here
}
Error
TypeError: Cannot read property 'length' of undefined
Try swapping the order of the checks:
if (Array.isArray(drugPrice.mailPrice.rejectMessage) && drugPrice.mailPrice.rejectMessage.length !== 0) {
code goes here
}
Validate your data, swapping the condition may help but it won't prevent, some errors from happeing. For example Array.isArray(drugPrice.mailPrice.rejectMessage) will throw an error if drugPrice.mailPrice is undefined.
if (drugPrice.mailPrice
&& drugPrice.mailPrice.rejectMessage
&& drugPrice.mailPrice.rejectMessage.length !== 0
&& Array.isArray(drugPrice.mailPrice.rejectMessage)) {
// code goes here
}
var drugPrice = { mailPrice: { rejectMessage: {} } };
if (drugPrice.mailPrice
&& drugPrice.mailPrice.rejectMessage
&& drugPrice.mailPrice.rejectMessage.length !== 0
&& Array.isArray(drugPrice.mailPrice.rejectMessage)) {
console.log('success');
} else {
console.log('fail')
}
NOTE
Always validate your data. Don't assume that you'll always get the right data. When working with objects always validate them, as doing data.name, can break your app, if data is null or undefined. for example, given the following object.
const drugPrice = { mailPrice: null };
doing, throws an error.
const drugPrice = { mailPrice: null };
// throws an error, Cannot read property 'rejectMessage' of undefined
if (Array.isArray(drugPrice.mailPrice.rejectMessage)) {
}
to prevent that from happening, we need to check if the propery exists, like the following.
const drugPrice = { mailPrice: null };
console.log(drugPrice.mailPrice && Array.isArray(drugPrice.mailPrice.rejectMessage) || 'Price is null or undefined')
You do not really need to actually do the .length !== 0. You can simply do:
if (Array.isArray(A.B.C) && A.B.C.length) { // <-- order is important here
//...
}
.length would be evaluated as a boolean and it will give you the same result as checking with !==0
That being said however your paths are quite long so you probably would want to make sure they are valid. Meaning if drugPrice or mailPrice are falsey you would have an issue. So usually you would want to check on them as well. Since your question was about the array part I will skip those but just as FYI.
You can build your own path checker or if you use libraries like lodash/underscore etc they always have a handy get/has functions to check like this (with lodash):
if (_.has(drugPrice, 'mailPrice.rejectMessage.length'))
//...
}
Obviously do not use those libraries just for that but if you already have them those methods are quite handy. You can simply check each of the paths as well via:
if (A && A.B && Array.isArray(A.B.C) && A.B.C.length) {
//...
}
It just gets tedious if you have long object paths etc.
The problem in your code is that javascript checks array length before checking if the array is the type of the array. You should change the order in the if statement.
You can try with:
if (myArr && Array.isArray(myArr) && myArr.length !== 0) {
// your code
}
Now the code is executed in the right order.
The first condition checks if myArr is defined,
The second condition checks if myArr is the type of Array, you can also do this way:
if (myArr && myArr.push && myArr.length !== 0) {
// your code
}
The third condition checks if myArr is not empty.
I am programming in Polymer 1.0 and am trying to create an IF function to change the value of a property. My function is the following:
_searchButton: function(selectednamedropdown, selectedtypedropdown){
if (selectednamedropdown=="no_name_selected" && selectedtypedropdown=="no_type_selected"){
this.searchUsagesBtn = true
} else{
this.searchUsagesBtn = false
}
}
In my mind when selectednamedropdown is equal to "no_name_selected" and selectedtypedropdown is equal to "no_type_selected" the function should set searchUsagesBtn to true and when they are not these values, false.
However, the function does not ever seem to be returning true even when these conditions are met. Any ideas why this might be? Thanks for all help
When I run your function like this:
let searchUsagesBtn;
function search(selectednamedropdown, selectedtypedropdown) {
if (
selectednamedropdown === "no_name_selected" &&
selectedtypedropdown === "no_type_selected"
) {
searchUsagesBtn = true;
} else {
searchUsagesBtn = false;
}
}
search("no_name_selected", "no_type_selected");
console.log("button: ", searchUsagesBtn);
I get button: true in console log. So maybe your inputs in this function are not a strings.
The issue was around how JavaScript treats properties within functions. The function was storing the new value and old value of the first property and not any values of the second property. The solution involved making 2 functions to test the strings in each property. Thanks for all assistance