This question already has answers here:
Is Chrome’s JavaScript console lazy about evaluating objects?
(7 answers)
Closed 5 years ago.
Javascript: I have a dynamically filled array named resultsAuthor, when I log this object, I get this. (logged it because I need the length to loop through the object and this wasn't working) 1
But when I try to log resultsAuthor.length, I get 0.
Anyone know what I'm doing wrong?
This is in my utils.js
From there I call it in my main.js like this:
var searchCriteria = document.querySelector('[title="tbxZoeken"]').value;
var searchAuthor = new Utils.GetBookinfoByAuthor(searchCriteria);
var resultsAuthor = searchAuthor.loadData();
console.log(resultsAuthor); // returns the object
console.log(resultsAuthor.length); // returns 0
Thanks!
Your ajax call has probably not finished loading when you print resultsAuthor.length, so it return 0.
If you print resultAuthor this is still a reference to the original variable, so it gets printed correctly.
To fix this you can use a callback function or a promise. With a callback you could do something like this:
In your utils.js
GetBookinfoByAuthor: function (auteur) {
//...
this.loadData = function(callback) {
// Rest of your code...
// Request returned sucessfully
if (xhr.status === 200) {
//Rest of your code....
for (var i = 0; i < data.length; i++) {
// add all books to array
}
// All books a loaded
callback(books)
}
}
}
In your main.js
var searchCriteria = document.querySelector('[title="tbxZoeken"]').value;
var searchAuthor = new Utils.GetBookinfoByAuthor(searchCriteria);
searchAuthor.loadData(function() {
console.log(resultsAuthor);
console.log(resultsAuthor.length);
});
Related
This question already has answers here:
Can't access object property, even though it shows up in a console log
(36 answers)
Is Chrome’s JavaScript console lazy about evaluating objects?
(7 answers)
Closed 3 years ago.
I have an object called "values" that contains a property "images" that is an array of strings. When I console.log "values", I do see the "images" property as an array of strings. However, when I console log values.images, the result is empty.
How could this be?
Here's the react-redux code:
I'm calling the confirm method.
const confirm = () => {
console.log("form values in confirm");
console.log(formValues);
let images = [];
for (let i = 0; i < formValues.images.length; i++) {
var reader = new FileReader();
reader.onload = function(e) {
images.push(e.target.result);
console.log('images base 64');
console.log(images);
};
reader.readAsDataURL(formValues.images[i].file);
}
formValues["images"] = images;
console.log("values after adding images");
console.log(formValues);
upload(formValues, history);
};
This snippet is from the action creator:
export const upload = (values, history) => async dispatch => {
console.log("images in uploadProduct action");
console.log("the whole object");
console.log(values);
console.log("values.images");
console.log(values.images);
};
-- edit --
The comments point out that the console.logs are lazily evaluated which is why I'm seeing the property when printing the whole object. Good to know. However, the goal is to in fact get the values.images property before further execution. How can I do that?
This question already has answers here:
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
(7 answers)
How do I return the response from an asynchronous call?
(41 answers)
Closed 5 years ago.
I wrote this simple function to check if certain images in an array are loadable, and placed the function close to the end of the JS file:
function checkImage(img) {
console.log(img);
return new Promise(resolve => {
var image = new Image();
var imgstatus = false;
image.onload = function() {
console.log(image);
console.log("img loaded");
imgstatus = true;
resolve(imgstatus);
};
image.onerror = function() {
console.log(image);
console.log("img error");
imgstatus = false;
resolve(imgstatus);
};
image.src = img;
});
}
It might be an overkill because I want to do was to check if each image file defined in a user-defined ('user' as in who can also edit the source-code) image array is loadable.
FYI, the array looks like this globally defined at the top of the JS file:
var userarray=["pics/blank.png", "pics/ape.png", "pics/orange.png", "pics/pear.png", "pics/blueberries.png", "pics/peach.png", "pics/grapes.png"];
So at the beginning of the same JS script I have this implemented within an initializing function (the first function in the JS file):
if (userarray != undefined && userarray.length == (mylength + 1))
{
var allfilespassed = 0;
for (var i=0; i < userarray.length; i++)
{
var tmp;
checkImage(userarray[i]).then(function(imgstatus){tmp=imgstatus; console.log(imgstatus);});
console.log(tmp);
if(!tmp)
allfilespassed = -1;
console.log(allfilespassed);
}
if(allfilespassed == 0) // all images passed
imagearray = userarray;
}
}
What is intriguing and frustrating to me is that in the console.logs:
pics/blank.png //perhaps from top level console.log(img); from the checkImage(img) function.
undefined //from console.log(tmp);
-1 //from console.log(allfilespassed);
pics/ape.png
undefined
-1
pics/orange.png
undefined
-1
pics/pear.png
undefined
-1
pics/blueberries.png
undefined
-1
pics/peach.png
undefined
-1
pics/grapes.png
undefined
-1
pics/ape.png //from console.log(image); inside image.onerror of the checkImage(img) function.
img error
false //from console.log(imgstatus); inside the .then() call, back up in the initialize function.
pics/blank.png
img loaded
true
pics/orange.png
img loaded
true
pics/pear.png
img loaded
true
pics/blueberries.png
img loaded
true
pics/peach.png
img loaded
true
pics/grapes.png
img loaded
true
Obviously, the values of variable imgstatus were undefined when I run the initialize function but the inner values of function checkImage came up later to show the results are what I expected (the "false" and "true"s came up later), i.e. "ape.png" is the only misnamed file in the array. It has to do with the order and priority of functions and objects are processed in the DOM - which I may also need some pointer, in case I have been doing other things correctly.
I also tried creating something using async and await, but there was not much help: (i.e. with same output from console.log)
async function waitImage(i) {
return await checkImage(i).then(function(imgstatus){return imgstatus;});
};
tmp = waitImage(userarray[i]);
What I got at the top of console.log instead of those undefined entries where a bunch of Promise { "pending" } objects.
So inside the same .then() of a promise, values are accessed at different time, leading to resolve value first being undefined, and then later on, in the same .then() the values are shown correctly.
No previous posts I have browsed through have explained clearly about the timeline in terms of DOM events when Promise and its resolution happens.
Please let me know your suggestions, especially on how to make it work.
I have a function which returns an array of two variables.
function exampleFunction() {
var variable1 = 'test';
var variable2 = 'test2';
return [variable1, variable2];
}
Now in another function when I call exampleFunction how do I get the items from the array that is returned from it.
I have tried using:
if (exampleFunction[0] == true) {
// do code here
}
To retrieve the values, you need to execute the function.
Update from
exampleFunction[0]
to
exampleFunction()[0] // paints "test"
You can also get the returned array into an other variable, and then access from it :
var myArray = exampleFunction()
myArray[0]
Hope it answers your question !
I have a angularJS factory created to insert and get some values from IndexedDB. I can successfully insert the values to the IndexedDB. But when i try to get the values out of the DB and pass it to the controller i face problems.
factory.getAllProgressData = function() {
var dbOptions = {};
dbOptions.include_docs = true;
var output = {};
var result = {};
pouchDb.allDocs(dbOptions, function(err, res) {
if (err)
console.log(err);
if(res) {
output.weight = getWeightValues(res.rows);
console.log(output); // <== This console line prints the object
}
});
console.log(output); // <== This console line does NOT print the object
return output;
};
var getWeightValues = function(rows) {
var weightValues = [];
for (var i = 0; i < rows.length; i++) {
weightValues.push(rows[i].doc.Weight);
};
return weightValues;
};
As you can see in the comments of the code, when i print the object to the console at the first place it prints. But when i try to do it bellow it doesn't print. And the return value is also empty. I'm very new to javascript and this behavior is not clear to me. I want the result object to be returned to the Controller. Please help. Thanks in advance.
Just guessing but maybe the answer is because pouchDb.allDocs is an asynchronous function. This might be a good opportunity for you to learn about writing asynchronous JavaScript (aka AJAX). AJAX is a difficult concept for those new to JavaScript.
For example, you should be able to clearly understand what gets printed to the console and in what order in the following code:
function printB() { console.log('B'); }
console.log('A');
setTimeout(printB, 10);
console.log('C');
The answer is ACB, not ABC, and not BAC. If you understand why, you are well on your way to answering your own question.
A slightly more relevant example:
var a = 'A';
function changeAtoB() { a = 'B'; console.log(a); }
console.log(a);
setTimeout(changeAtoB, 10);
console.log(a);
The answer is AAB, not ABA, for the same reasons as the previous example. In addition, note that setTimeout does a specific thing, but it is a good general introductory example of the concept of an asynchronous function.
To address your question more directly, the second example corresponds to why your output variable is probably defined for one call to console.log but not the other.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Javascript closure inside loops - simple practical example
I am using webservice to get the data in the form of JSON by using javascript and want to store that data in Sqlite Database. here i used for loop to store data one by one in Database by executeSql Query. But problem is function inside the for loop getting "i" value out of scope means showing undefined. I am trying to solve this problem by last 5 days. Any suggestion ?
Thanks
function GetGeoValues() {
$.get("http://example.in/projects/api.php?usn=user&pwd=****&var=something", function (Jdata) {
var geoid = new Array();
var geoname = new Array();
var i;
for (i = 0; i < Jdata.vact_geography.length; i++) {
geoid.push(Jdata.vact_geography[i].geo_id);
geoname.push(Jdata.vact_geography[i].geo_name);
db.transaction(function (transaction) {
alert(geoid[i]); // here i showing undefined
transaction.executeSql('INSERT INTO vact_geography VALUES(' + parseInt(geoid[i]) + ',"' + geoname[i] + '")');
});
}
});
}
I'm not sure, but this can happen, if function(transaction) executed in asynchronous mode. In this case variable i after for loop is finished must be equals to Jdata.vact_geography.length, and, as result geoid[i] equals to undefined. To workarround this try next:
function GetGeoValues() {
$.get("http://example.in/projects/api.php?usn=user&pwd=****&var=something",
function(Jdata) {
var geoid=new Array();
var geoname=new Array();
for(var i=0;i<Jdata.vact_geography.length;i++) {
geoid.push(Jdata.vact_geography[i].geo_id);
geoname.push(Jdata.vact_geography[i].geo_name);
}
db.transaction(function(transaction) {
for(var i=0;i<geoid.length;i++) {
alert(geoid[i]); // here i showing undefined
transaction.executeSql('INSERT INTO vact_geography VALUES('+parseInt(geoid[i])+',"'+geoname[i]+'")');
// All INSERT's executed in one transaction
}
});
}
);
}
Here inner function and outer function concept is considered. So the outer function have the var i. But in inner function i is not defined. Thats y its throwing error as "undefined"