I want to export a variable called recettesFromIngredients from search-box.js to ingredients-logic.js.
So to be more precise recettesFromIngredients is a variable with an empty array at first.
But then I fill this empty array here:
function ingredients(enteredValue) {
for (let i = 0; i < recettes.length; i ++) {
for (let d = 0; d < recettes[i].ingredients.length; d++) {
if ( recettes[i].ingredients[d].ingredient.toLocaleLowerCase().includes(enteredValue)) {
recettesFromIngredients.push(recettes[i]); // <-----------
};
};
};
};
So what I am trying to do is: once I fill this array I want to export it.
This is what I tried to do
export {recettesFromIngredients} // at the bottom of the file after the every function is called
In the console I don't have any error the export/import seems to be ok but when I console log this Var in the imported file I got an empty array while in the export file the array is filled as wanted!
What could be the problem that I am getting an empty array in ingredients-logic.js? Should I export from another position in the file or in another way?
Why don’t you try to export the function instead? Then you can call the function in another file , the function will return the filled array.
You have to return the array in the function call as well.
Your code should look like :
export default function ingredients(enteredValue) {
let recettesFromIngredients = [];
for (let i = 0; i < recettes.length; i ++) {
for (let d = 0; d < recettes[i].ingredients.length; d++) {
if ( recettes[i].ingredients[d].ingredient.toLocaleLowerCase().includes(enteredValue)) {
recettesFromIngredients.push(recettes[i]); // <-----------
};
};
};
return recettesFromIngredients
};
import the function in another file , then
call the function
const x= ingredients(enteredValue)
now const x has the array
Related
import React from 'react';
const RowArray=()=>{
return(
<div>
<h1>Row Array</h1>
</div>
)
};
const chunk_array = (list, integer)=>{
let temp_arr = list;
console.log('chunks',list,'integer',integer);
const list_of_chunks = [];
const iteration = Math.ceil(+list.length/+integer);
// list.map(x => {console.log(x,"map")})
for (let i;i< iteration ;i++ ){
console.log(i);
let temp_chunk = temp_arr.splice(6, temp_arr.length);
list_of_chunks.push(temp_chunk);
};
return list_of_chunks;
}
const TableArray=({details})=>{
const data = chunk_array(details);
console.log('data', data);
return(
<div className="d-flex flex-row">
<RowArray/>
</div>
)
};
export default TableArray;
the for loop in function chunk array won't work, supported as no i was logged in the console. I understand in jsx for loop may not work, I believe I define the function in pure javascript enviroment, so why do you think it is?
Console.log(i) doesn't log anything, as in the function skipped for loop line
you haven't initialized the value of i in the for loop
for (let i = 0; i < iteration; i++) {
// your code
}
chunk_array function expects two arguments and you're only passing one argument details
I am new to ReactJS, I am trying to create 10 buttons with for loops, and set a variable with the integer from the for loop, however the function setMqty(i) always returns 11 for all the buttons. What is the correct way for doing this?
var qtyButtons = [];
for(var i = 1; i < 11; i++) {
qtyButtons.push(<div
onClick={(btn) => {qtyBtnToggle(btn);setMqty(i); }}
>
{i}
</div>)
}
Thank you in advance.
The main issue here has to do with scoping. Let me reduce your example to a more minimal example:
var qtyCallbacks = [];
for (var i = 1; i < 11; i++) {
qtyCallbacks.push(() => console.log(i));
}
for (const callback of qtyCallbacks) {
callback();
}
What's going wrong here? Why is it only logging 11 and not 1-10?
The issue is that a variable defined with var are scoped to the nearest function or globally if not in a function. So what does this mean?
It means that each iteration in your for loop refers to the same i. This isn't an issue if you directly use i.
for (var i = 1; i < 11; i++) {
console.log(i); // logs 1-10
}
However it does become an issue if you refer to i in code that is executed at a later point. The reason the initial snippet only logs 11 is because all the callbacks are created, each one referring to the same i. So when you evoke each callback after the for-loop is complete, they will all refer to the current value (which is 11).
for (var i = 1; i < 11; i++) {
}
console.log(i); // logs 11
// so if we invoke the callbacks here they all log 11
So how do you solve this issue? The simplest solution is probably to replace var with let. let will create a new variable for each for-iteration. Meaning that each created callback will refer to their own i and not a shared i. This also means that you cannot access i outside of the for-loop.
var qtyCallbacks = [];
for (let i = 1; i < 11; i++) {
qtyCallbacks.push(() => console.log(i));
}
for (const callback of qtyCallbacks) {
callback();
}
console.log(i); // expected error, `i` is only available within the for-block
I think using a map function is the correct way for doing it.
Therefore, you must generate a range of numbers our any element to be able to perform a map function.
So if i was in your place i would have do it like:
const [mqty, setMqty] = useState(0);
// ...
const qtyButtons = Array(10).fill().map((_, i) => {
const value = parseInt(i);
return (
<button onClick={handleClick(value)}>
{value}
</button>
);
});
// ...
// The trick here is that function returning another function, beware of that
const handleClick = (i) => () => {
setMqty(i);
};
I am guessing setMqty is a state.Can you try
setMqty(currentValue=> currentValue+1)
I have the following ReactJS code which I am using to render a number of buttons which will allow the user to navigate around the data returned from an API (a bunch of paginated images).
I have the multiple buttons displaying but they send i as 19 (the end value in the loop) to the handlePageClick() function.
How can I get the value of i to be passed to my handlePageClick() function?
handlePageClick( button ) {
console.log( button );
this.setState( prevState => {
return {
currentPage: button
}
}, () => {
this.loadMedia();
});
}
render() {
// figure out number of pages
const mediaButtonsNeeded = parseInt( this.state.totalMedia / this.state.perPage )
var mediaButtons = [];
for (var i = 0; i < mediaButtonsNeeded; i++) {
mediaButtons.push(<button onClick={() => this.handlePageClick(i)}>{i}</button>);
}
return (
<div>
<div>
<h1>Media test</h1>
{media}
{mediaButtons}
</div>
</div>
)
Since var is global scope variable declaration, your loop always rewrite i to next value.
Easiest solution is just replacing from var to let.
for (let i = 0; i < mediaButtonsNeeded; i++) {// your code...
This should work:
for (var i = 0; i < mediaButtonsNeeded; i++) {
mediaButtons.push(<button onClick={() => this.handlePageClick(i+"")}>{i}</button>);
}
First take a look at my simple codes below:
function mySecondFunction(objArray,setFunc)
{
for (let i = 0; i < objArray.length; i++)
{
objArray[i].info.setTop(72);
}
}
function myFunction()
{
let myObjArray = [];
for (let i = 0; i < 10; i++)
{
myObjArray.push({
info:{topVar:0,
bottomVar:0,
get top() {return this.topVar;},
get bottom() {return this.bottomVar;},
setTop: function(input) {this.topVar = input;},
setBottom: function(input) {this.bottomVar = input; }
}
});
}
mySecondFunction(myObjArray); // This works Fine
mySecondFunction(myObjArray,setTop); // I want something like this!!!
}
As you can see, I want to pass a method of an object to another function. I know a lot of possible solutions to avoid this, but I want to know whether it is possible or not.
Detach it and pass as an argument. Remember to use call to set the intended this value.
function mySecondFunction(objArray, setFunc)
{
for (let i = 0; i < objArray.length; i++)
{
setFunc.call(objArray[i].info, 72);
/* explicitly telling that:
please set 'this' value in this function to be 'objArray[i].info' when running,
allowing, e.g. `this.topVar` in
`setTop: function(input) {this.topVar = input;}`
to be operating on `objArray[i].info.topVar` */
}
}
function myFunction()
{
let myObjArray = [];
for (let i = 0; i < 10; i++)
{
myObjArray.push({
info:{topVar:0,
bottomVar:0,
get top() {return this.topVar;},
get bottom() {return this.bottomVar;},
setTop: function(input) {this.topVar = input;},
setBottom: function(input) {this.bottomVar = input; }
}
});
}
mySecondFunction(myObjArray, myObjArray[0].info.setTop);
/* once detaching the method from the object,
(if we are not using arrow functions),
we lose 'this' value, meaning we are losing
the target of object that we want to operate on */
console.log(myObjArray)
}
myFunction();
You can target item number in the array list. You can do statically (i.e. 1-???) or dynamically with an iteration and a variable. You can then the object property within that. For example:
myObjArray[0].info.setTop
That will target the 1st item in the array. Be sure to omit parentheses (()) when passing the method as you want to pass the function reference not the result
function createTextFields(obj) {
for (var i = 0; i < obj.length; i++) {
var dataDump = {};
for (var key in obj[i]) {
var textField = Ti.UI.createTextField(pm.combine($$.labelBrown, {
left: 200,
height:35,
value:obj[i][key],
width:550,
keyboardType:Ti.UI.KEYBOARD_NUMBER_PAD,
layout:'horizontal',
backgroundColor:'transparent',
id:i
}));
dataDump[key] = textField.value;
var callback = function (vbKey) {
return function (e) {
dataDump[vbKey] = e.source.value;
};
}(key);
}
globalData.push(dataDump);
}
}
I am using the simlar code for Adding the data and it works fine. I posted the problem yesterday and it got resolved...
Last Object is always getting updated?
Now when i go to edit page, it shows me four text fields or number of text fields added... now when i edit something and click on save... the value get's updated on the fourth or the last TextFields Object...
Don't define functions inside loops. Computationally expensive and leads to problems, like this one. Here's a fix that should solve it:
function createTextFields(obj) {
var callback = function (vbKey, localDump) {
return function (e) {
localDump[vbKey] = e.source.value;
};
}
var i;
var max = obj.length;
for (i = 0; i < max; i++) {
var dataDump = {};
for (var key in obj[i]) {
dataDump[key] = textField.value;
var callBackInstance = function(keyn, dataDump);
}
globalData.push(dataDump);
}
}
JavaScript does not have block level scope, so your variables dataDump and callback, though "declared" inside for-loops actually belong to the function. As in, you're saving a value to dataDump, then you're overwriting it, each time you go through the loop. Which is why finally only the code that operated on the last value remains.
Take a look at What is the scope of variables in JavaScript? too.