I have search functionality that allows you to search for cryptocurrencies and I'm trying to have it where if the param/coin that is searched doesn't match with the API's title of the coin or symbol, an alert box would pop up telling the user to try again.
The problem I'm having is that if the if statement is true and there's a match, the else statement/alert box pops up regardless. Here's my code within my axios request:
cryPrice(param){
axios.get(`https://api.coinmarketcap.com/v1/ticker/?limit=0`)
.then(res => {
const cryptos = res.data;
const price = []
for(let title in cryptos){
const cryptoTitle = cryptos[title].name.toUpperCase();
const cryptoSymbol = cryptos[title].symbol.toUpperCase();
if(cryptoTitle === param || cryptoSymbol === param){
price.push(cryptos[title].price_usd);
}else{
alert("Please try again");
break;
}
}
this.setState({
priceResults: price
})
})
}
Your code loops through every single item in the array, as soon as a non-matching item is encountered it alerts and breaks the loop
What you probably want is more like
cryPrice(param){
axios.get(`https://api.coinmarketcap.com/v1/ticker/?limit=0`)
.then(res => {
const priceResults = res.data
.filter(item => [item.name.toUpperCase(), item.symbol.toUpperCase()].includes(param))
.map(item => item.price_usd);
if (priceResults.length) {
this.setState({priceResults});
} else {
alert("Please try again");
}
})
}
You find a match on some of the elements but alert about every other, all of those that do not match param. You should probably only alert after the loop execution has stopped and iff there were no currencies matched.
Related
I have a list of urls and need to check the same element on every of them.
But there are 2 conditions:
all must be done in 1 it()
test must not fail after the first wrong url, but must check all of them and show result only after list finishing
I tried to do it by loop and try-catch (because there is not soft asserting by default), but then the test always was passed, even when text from element was wrong (as I undestand it's because of asynchronicing).
let errorUrls = []
for (let url in data.PRODUCTS_PAGES) {
cy.visit(url)
cy.get('div.configurator-controls span').invoke('text')
.then(text => {
try {
expect(text).to.equal(data.PRODUCTS_PAGES[url])
} catch (e) {
errorUrls.push(e.message)
}
})
}
expect(errorUrls).to.be.empty
How can I do this?
If you don't want to fail, don't use the expect() in the loop.
Note, all URL's must be same-origin.
let errorUrls = []
for (let url in data.PRODUCTS_PAGES) {
cy.visit(data.PRODUCTS_PAGES[url])
cy.get('div.configurator-controls span').invoke('text')
.then(text => {
if (text !== data.PRODUCTS_PAGES[url]) {
errorUrls.push(e.message)
}
})
}
cy.then(() => {
cy.log(errorUrls)
expect(errorUrls).to.have.length(0)
})
You can do something like this:
let errorUrls = []
for (let url in data.PRODUCTS_PAGES) {
cy.visit(data.PRODUCTS_PAGES[url])
cy.get('div.configurator-controls span').then(($ele) => {
if ($ele.text() == data.PRODUCTS_PAGES[url]) {
expect($ele.text()).to.equal(data.PRODUCTS_PAGES[url])
} else {
errorUrls.push(data.PRODUCTS_PAGES[url])
}
})
}
cy.then(() => {
expect(errorUrls).to.be.empty
})
everyone, I have some problem with fetching data and displaying message on initial loading as well as when I change some of the input filed value. The idea here is to display specific message in two cases after doing some calculation.
const potrosnja = document.getElementById('potrosnja');
const nagib = document.getElementById('nagib');
const input = document.querySelectorAll('input[type="number"]');
const submitBtn = document.getElementById('submitBtn');
const poruka = document.getElementById('poruka');
let str = document.querySelector('input[name="strane-sveta"]:checked').value;
let godisnjaPotrosnja = parseInt(potrosnja.value);
let nagibKrovaInput = nagib.value;
//On button submit it fetches data and calculate the value needed for yearly consumption of energy
//fetching data
async function dataFetch(){
let response = await fetch('./csvjson.json')
let data = await response.json();
data.map(strana => {
strana.strana.map((item, i) => {
try {
if(item == str && nagibKrovaInput == strana.nagib) {
let result = Math.ceil(godisnjaPotrosnja / strana.vrednost[i]);
console.log("try works")
poruka.innerHTML = `You need <span class="kw">${result}</span>`
}
}
catch(err) {
poruka.innerHTML = `Please fill required fields.`
console.log(err)
}
})
})
}
//event listeners
submitBtn.addEventListener('click', () => {
dataFetch()
console.log('clicked')
input.forEach(input => {
if(input.value == ''){
input.classList.add("active");
}
})
})
I can see that the problem is inside try function, it like condition isn't treated on initial load, and I have to reload page so it would work. Can someone help me understanding what is the problem?
Ok, I found solution... First thing I have to do Is to check if nagibKrovaInput == strana.nagib, after I get true, I compared does the indexOf item is equal as str and after I get true, it will display something. I also changed on click on the button to send values to data function as an arguments and It solved the problem. Tnx for help.
I'm pretty new to coding and to Velo from Wix, therefore I need help.
I created a member's page, the page gets the pricing plan that the member subscribed to, and it shows a specific form to be submitted in order to set a dashboard according to the region he/she selects.
When the user submits the form, my code checks for duplicates like email and field values. If the user has already submitted it an error will appear telling the user that the form was already submitted, if the value is "" or equal to another one, another message will appear and tells the user to check the selection and make 3 different selections.
Well for the Free Plan where only one dropdown is shown, everything runs smoothly, for the Basic where I have 3 dropdowns nothing works. So... let' go to the code:
import wixData from 'wix-data';
import wixUsers from 'wix-users';
$w.onReady(function () {
console.log("Ready")
let user = wixUsers.currentUser
user.getPricingPlans()
.then ((pricingPlans) => {
let firstPlan = pricingPlans[0];
let planName = firstPlan.name;
if (planName == '7 DAY FREE TRIAL $0'){
$w('#text30').show();
$w("#text31").show();
$w('#dropdown1').show();
$w('#emailInput').show();
$w('#button1').show();
searchForDuplicityFreePlan();
}
if(planName == 'BASIC'){
$w('#text30').show();
$w("#text31").show();
$w('#dropdown2').show();
$w('#dropdown3').show();
$w('#dropdown4').show();
$w('#emailInput2').show();
$w('#button2').show();
searchForDuplicityBasicPlan();
}
});
});
async function searchForDuplicityFreePlan(){
$w("#dataset1").onBeforeSave(async() => {
let checkEmailFreeOk = await checkEmailFree();
let fieldCheck = $w("#dropdown1").value;
if(checkEmailFreeOk === false){
$w("#text32").text = "An error occurred. You have already submitted this form";
return false
}
if(fieldCheck === ""){
$w("#text32").text = "An error occurred. Please select your region of interest";
return false
}
})
}
async function checkEmailFree(){
let flagFree = true
await wixData.query('RegionSelectionQuizFree')
.eq('email', $w("#emailInput").value)
.find()
.then((result)=>{
if(result.items.length > 0)
flagFree = false
})
return await flagFree
}
async function searchForDuplicityBasicPlan(){
$w("#dataset2").onBeforeSave(async() => {
let checkEmailBasicOk = await checkEmailBasic();
let region1 = $w("#dropdown2").value;
let region2 = $w("#dropdown3").value;
let region3 = $w("#dropdown4").value;
const regions = new Set();
regions.add(region1);
regions.add(region2);
regions.add(region3);
regions.delete("");
if(checkEmailBasicOk === false){
$w("#text34").text = "An error occurred. You have already submitted this form";
return false
}
if (regions.size !== 3) {
$w("#text34").text = "An error occurred. Please select 3 different regions of interest";
return false
}
})
}
async function checkEmailBasic(){
let flagBasic = true
await wixData.query('RegionSelectionQuizBasic')
.eq('email', $w("#emailInput2").value)
.find()
.then((result)=>{
if(result.items.length > 0)
flagBasic = false
})
return await flagBasic
}
My function should assign an employee on a seat if the seat is available. I do not understand why the program doesn't act as synchronous even though I used "await".
In the first lines of the function, the program acts as expected. it waits to get "seats"from the database, then performs the "if(seats.length > 0)"
check and initialises an empty array.
async function AssignSeat(req, res) {
var seats = await connection.SeatEmployees.findAll({
where: {
SeatId: req.body.seat.SeatId
}
})
.catch(err => {
res.status(err.status).json(err)
});
if(seats.length > 0){
var isShared = true;
var employees = [];
await seats.forEach(async function(seat){
var employee = await connection.EmployeesGraph.findAll({
where: {
id: seat.EmployeeGraphId
}
})
.catch(err => {
res.status(err.status).json(err)
});
employees.push(employee);
})
.catch(err => {
res.status(err.status).json(err)
});
employees.forEach(employee => {
if(employee.frequent == true)
isShared = false;
})
if(isShared == true){
//assign user to seat;
}
}
}
My problem is at the 13th line of code, at " await seats.forEach(async function(seat)".
What I want to do is go through each element of "seats", Get the employee assigned to that seat, and push it into the "employees" array.
Only after iterating from all the seats and filling the employees array, I want proceed with the "employees.forEach(employee => {" line.
Instead, what happens is that after calling
-----"var employee = await connection.EmployeesGraph.findAll({ "---- ,the program doesn't wait for sequelize to get the employee from the database and then go to ----"employees.push(employee);"---- , as intended.
It goes to the paranthesis on the line after ----"employees.push(employee);"---- , then I get the error "TypeError: Cannot read property 'catch' of undefined".
Could you please explain why this happens?
The easiest solution is to use an actual for loop instead of forEach for this task. forEach() won't wait to iterate over everything.
try {
for (const seat of seats) {
var employee = await connection.EmployeesGraph.findAll({
where: {
id: seat.EmployeeGraphId
}
})
.catch(err => {
res.status(err.status).json(err)
});
employees.push(employee);
}
} catch (err) {
res.status(err.status).json(err)
}
I have this function that is supposed to get referral codes from users. User gives a code and the referral code checked if it exists in the database then evaluated if
it does not match the current user, so that one should not refer himself and
it is a match with one of the codes in the database
This code however just does not find a match even if the code given is in the database. If the referral code matches the one of the current user, it works correctly and points that out i.e one cannot refer themselves.
But if the referral code is a match to that of another user which is how a referral system should work, it still says no match.
How can I remove this error
export const getID = functions.https.onCall(async(data, context) => {
const db = admin.firestore();
const usersSnapshot = await db.collection("user").get();
const allUIDs = usersSnapshot.docs.map(doc => doc.data().userID);
const userID = context.auth.uid;
const providedID = "cNx7IuY6rZlR9mYSfb1hY7ROFY2";
//db.collection("user").doc(providedID).collection("referrals").doc(userID);
await check();
function check() {
let result;
allUIDs.forEach(idFromDb => {
if (providedID === idFromDb && (idFromDb === userID)) {
result = "ownmatch";
} else if (providedID === idFromDb && (idFromDb !== userID)) {
result = "match";
} else {
result = "nomatch";
}
});
return result;
}
if (check() === "match") {
return {
message: `Match Found`,
};
} else if (check() === "ownmatch") {
return {
message: `Sorry, you can't use your own invite code`,
};
} else {
return {
message: `No User with that ID`
};
}
});
(This is not an answer, but a simple refactoring.)
This is what your code is currently doing (roughly, I didn't run it):
const resultMsgs = {
nomatch: 'No User With That ID',
ownmatch: 'Sorry, you can\'t use your own invite code',
match: 'Match Found',
}
function check(uids, providedId, userId) {
let result
uids.forEach(idFromDb => {
if (providedId !== idFromDb) {
result = 'nomatch'
return
}
if (userID === idFromDb) {
result = 'ownmatch'
return
}
result = 'match'
})
return result
}
export const getID = functions
.https
.onCall(async (data, context) => {
const userId = context.auth.uid
const providedId = 'cNx7IuY6rZlR9mYSfb1hY7ROFY2'
const db = admin.firestore()
const user = await db.collection('user').get()
const uids = user.docs.map(doc => doc.data().userId)
const checkResult = check(uids, providedId, userId)
return { message: resultMsgs[checkResult] }
})
(I removed the seemingly-spurious db collection operation.)
Your forEach is iterating over all of the uuids, but result will be set to whatever the last comparison was. Perhaps this is correct, but:
If you're looking for any match, this is not what you want.
If you're looking for all matches, this is not what you want.
If you're looking to match the last UUID, it's what you want, but an odd way to go about it.
So:
If you want any matches, use... ahem any form of an any function.
If you want all matches, use any form of an all function.
If you want the first match, then just check the first element.
If you want the complete set of comparisons then you'll need to use map instead of forEach, and handle each result appropriately, whatever that means in your case.
In any event, I'd recommend breaking up your code more cleanly. It'll be much easier to reason about, and fix.