Converting a for loop function results into an array - javascript

I am looping through an array of selected index comparing each value to a database of machine pricing, and returning the price of each selected index. the problem is, the result repData1 return individual results, I want those resuls to displayed in an array for I can manipulate the array.
I have tried push, concat.... string results is displayed for each item rather than a whole.
for (let a = 0; a < selectedindex.length; a++) {
wixData
.query('MachinePricing')
.contains('title', selectedindex[a])
.find()
.then(async (results) => {
if (results.items.length > 0) {
let repData = results.items;
let repData1 = repData.map(({ prices }) => prices);
console.log(repData1);
}
});
}

Don't loop async calls using iterators
Instead do this
const a = 0
const repData = [];
function getData = () => {
if (a >= selectedindex) {
processRepData();
return;
}
wixData
.query('MachinePricing')
.contains('title', selectedindex[a])
.find()
.then(results => {
if (results.items.length > 0) {
repData.concat(results.items.map(({prices}) => prices));
}
a++;
getData()
});
}
getData()

I think what you are doing is this (run a query for each selected index and extract the returned prices into an array):
const queries = selectedindex.map(ix => wixData
.query('MachinePricing')
.contains('title', ix)
.find())
const results = await Promise.all(queries)
const prices = results.flatMap(r => r.items.map(i => i.prices))

Related

iterating Javascript array and delete based on condition

I want to iterate through an array of words, look up the definition and delete the word if no definition is found.
my code looks as follows;
var words = ["word1", "word2", "word3",]
function Meaning(words){
const getMeaning = async () => {
const response = await fetch(`https://api.dictionaryapi.dev/api/v2/entries/en/${words}`)
const myJson = await response.json()
for(i = 0; i < words.length; ++i) {
if(!response[i]){
myJson.splice(i,1)
console.log(myJson)
}
}}
This is not really doing anything atm. Where am I going wrong?
edit to add context
tried like this as well;
for(i = 0; i < words.length; ++i)
fetch(`https://api.dictionaryapi.dev/api/v2/entries/en/${words[i]}`).then((response) => {
if (response === 404) {
let response = words
words[i].splice(i,1)
console.log(response)
}
throw new Error('Something went wrong');
})
.then((responseJson) => {
let response = words
response[i].splice(i,1)
})
.catch((error) => {
console.log(error)
});
I can print out the 404 error when it finds no definition, but I can't remove it from the words array
After quick look at the API, and it appears to handle only single words, so the caller needs to make the requests one at a time. Here's how to do it...
const baseUrl = 'https://api.dictionaryapi.dev/api/v2/entries/en/';
// one word lookup. resolve to an array of definitions
async function lookupWord(word) {
const res = await fetch(baseUrl + word);
return res.json();
}
// resolve to a bool, true if the word is in the corpus
async function spellCheck(word) {
const defArray = await lookupWord(word);
return Array.isArray(defArray) && defArray.length > 0;
}
// create a spellCheck promise for every word and resolve with the results
// note, this mutates the array and resolves to undefined
async function spellCheckWords(array) {
const checks = await Promise.all(array.map(spellCheck));
for (let i=array.length-1; i>=0; i--) {
if (!checks[i]) array.splice(i,1);
}
}
// test it (a little)
let array = ['hello', 'whereforeartthou', 'coffee'];
spellCheckWords(array).then(() => {
console.log(array)
})
try this code, you need to check every single element of array from response
var words = ["word1", "word2", "word3"];
function Meaning(words) {
const getMeaning = async () => {
const response = await fetch(`https://api.dictionaryapi.dev/api/v2/entries/en/${words}`)
const myJson = await response.json()
let result = [];
myJson.forEach(element => {
if(words.includes(element)) {
result.push(element)
}
});
return result;
}
return getMeaning();
}

can't iterate over an array in java script

iam traying to iterate over an array in js but it's not work and and i always get length equal 0 and when i try to access elements by index i get undefined but when i try to print my array by clg it worked well here is my code
function getData(url) {
let arr = []
fetch(url).then(response => response.json()).then(data => {
for (let index = 0; index < data.length; index++) {
arr[index] = data[index].content
}
})
console.log(arr)
}
with console.log (arr) this the result
[]
0: "any"
1: "any"
2: "any"
3: "any"
length: 4
[[Prototype]]: Array(0)
but with console.log (arr[0]) i got
undefined
i want to get result from fetch and convert it to array and iterate over this array
You should return the Promise and the arr too. Then in a .then set the referenc you want.
function getData(url) {
return fetch(url).then(response => response.json()).then(data => {
let arr = [];
for (let index = 0; index < data.length; index++) {
arr[index] = data[index].content
}
return arr;
})
}
getData(url).then(contents => { /*... do whatever you want */ });
You can use async/await, so itt will be easier to manage callbacks
async function getData(url) {
return fetch(url).then(response => response.json()).then(data => data.map(d => d.content));
}
const contents = await getData(url);
for(const content of contents){
/*... do whatever you want */
}

Running forEach on Object.entries does not return the same thing as a for loop

I am iterating over an object using a regular for loop and that works fine for me. But, I was trying to remove all for loops of my code in favor of array iteration instead and, for some reason I can't understand why when using forEach I get a different result.
Note: forEach here is from a module called p-iteration
https://www.npmjs.com/package/p-iteration
This works fine, it returns the correct values.
for await (const [key, value] of Object.entries(tatGroupedByRegion)) {
onTarget = 0;
notOnTarget = 0;
const cases = [];
await forEach(value, async email => {
if (!cases.includes(email.new_name)) {
cases.push(email.new_name);
isOnTarget(email);
}
});
backlogData[key].tatd1 = percentage(onTarget, notOnTarget);
tatd1Total.value += parseInt(percentage(onTarget, notOnTarget), 10);
if ((parseInt(percentage(onTarget, notOnTarget) !== 0), 10)) {
tatd1Total.count += 1;
}
}
This does not work,this part here backlogData[key].tatd1 = percentage(onTarget, notOnTarget), returns the same value over and over.
await forEach(Object.entries(tatGroupedByRegion), async ([key, value]) => {
onTarget = 0;
notOnTarget = 0;
const cases = [];
await forEach(value, async email => {
if (!cases.includes(email.new_name)) {
cases.push(email.new_name);
isOnTarget(email);
}
});
backlogData[key].tatd1 = percentage(onTarget, notOnTarget);
tatd1Total.value += parseInt(percentage(onTarget, notOnTarget), 10);
if ((parseInt(percentage(onTarget, notOnTarget) !== 0), 10)) {
tatd1Total.count += 1;
}
});
exports.forEach = async (array, callback, thisArg) => {
const promiseArray = [];
for (let i = 0; i < array.length; i++) {
if (i in array) {
const p = Promise.resolve(array[i]).then((currentValue) => {
return callback.call(thisArg || this, currentValue, i, array);
});
promiseArray.push(p);
}
}
await Promise.all(promiseArray);
};
This is the implementation of forEach that you're using. The callback receives this as the first argument, this can be a problem.

Javascript map, reduce not working when implemented within object method

Based on the answer from this question I implemented the map reduce code within an object method.
this.displayValueGraph = async () => {
let scaleData = [];
this.positions.forEach(async (pos, i) => {
scaleData[i] = [];
let gdata = await pos.graphData;
gdata.option.forEach((d) => {
scaleData[i].push(d.map((x) => x * pos.size));
});
});
let out;
if (scaleData.length == 1) {
out = scaleData[0];
} else {
out = scaleData.reduce((a, b) => b.map((x, j) => x.map((v, k) => a[j][k] + v)));
}
};
The code by itself works fine. I have taken the input data (above scaleData) and run it through the map reduce function and the output is as expected. But if I include it as part of this method it does nothing. It doesn't throw any errors, it simply returns an empty array.
I have tried adding an empty array as an "initial value", but it doesn't help.
The root cause of the problem appears to have been the first forEach loop, where I included an await. I replaced the forEach with for in and it solved the problem.
this.displayValueGraph = async () => {
let scaleData = [];
for (const i in this.positions) {
const pos = this.positions[i];
scaleData[i] = [];
let gdata = await pos.graphData;
gdata.option.forEach((d) => {
scaleData[i].push(d.map((x) => x * pos.size));
});
}
let out;
if (scaleData.length == 1) {
out = scaleData[0];
} else {
out = scaleData.reduce((a, b) => b.map((x, j) => x.map((v, k) => a[j][k] + v)));
}
};

Take the average of an array items

Try to get average of values. I have json data going inside that, grabbing the array and using the average function on it. But error returns...
TypeError: arr.reduce is not a function
It's from first console.log(myArray) as per screenshot below. and second console.log with avg function, not working...
data() {
return {
myArray:[],
}
},
methods: {
avgArray: function(){
const sum = arr => arr.reduce((a,c) => (a + c));
const avg = arr => sum(arr) / arr.length;
this.estates.forEach((a, index) => {
this.myArray = a.m2_price;
console.log(this.myArray);
});
console.log(avg(this.myArray));
}
}
avgArray: function(){
const sum = arr => arr.reduce((a,c) => (a += c),0); // add equals and init with 0
const avg = arr => sum(arr) / arr.length;
this.myArray = this.estates.map(a => a.m2_price)
console.log(avg(this.myArray));
}
You were setting this.myArray as a value and not an array. You could've either pushed the m2_price or map it like above
Reduce function only exists on arrays. Clearly you were logging this.myArray and getting integers. Hence the error.
That is what reduce is for
const average = array => (array && array.length) ? (array.reduce((sum, item) => sum + item, 0) / array.length) : undefined;
console.log(average([1,2,3,4,5,6]));
export the average function from a file called average.js
Applied to your situation
import { average } from 'pathToYourIncludeLibrary/average';
data() {
return {
myArray:[],
}
},
methods: {
avgArray: () => average(this.myArray)
}

Categories

Resources