For Loop never executing (Javascript / Jquery) [duplicate] - javascript

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
(7 answers)
Closed 6 years ago.
So the for loop runs if I replace$.get('/preceed_with_an.txt', function(data){var ans = data.split('\n')}); with ans = ["filler","more filler"] but when the $.get line is in it refuses to execute the for loop and nothing is ever written to the console. For context, I am writing code that tells you if you should use A or AN before a word. Words that you use an for are all on separate lines in preceed_with_an.txt I have checked an the $.get functions and the file is written to the array just fine.
$(document).on('input',$('#givenWord'),function(){
var ans = new Array;
$.get('/preceed_with_an.txt', function(data){var ans = data.split('\n')});
for (var i = 0; i < ans.length; i++){
console.log("help");
if (ans[i] == $('#givenWord').lower){
var answer = $("#answer");
console.log("AN");
$(answer).text("An");
break;
}else{
var answer = $("#answer");
console.log("A")
$(answer).text("A");
}
}
});

The get() is asynchronous, so ans.length is equal to zero because the data return after the for loop execution.
You have to execute the for loop in the get() callback function:
$.get(url, function(data) {
var arr = data.split(',');
for(...) {
//...
}
});
Execution flow (your code)
Create ans array
Call the get() function
Try to execute the for loop (without available data)
get() return the data
Asynchronous call
Create ans array
Call the get() function with the for loop in the callback
get() returns data and executes the callback --> for loop with data
EXAMPLE
Check the console for the results. Even if the setTimeout function is called before the console.log(), the code continued the execution and waited for the callback's answer (after 1 second). When the result came out, the callback executed:
var def = $.Deferred();
def.done(function(data) {
console.log(data);
});
//Asynchronus call (delays for 1 second)
setTimeout(function() {
def.resolve('Callback after 1 second')
}, 1000);
//Execute immediately
console.log('Write something!');
//Console results
// 1. Write something
// 2. callback (after 1 second)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Check these links about asynchronous functions:
jQuery.get()
Async

Related

executeScript get return variable and sendResponse in chrome extension [duplicate]

This question already has answers here:
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
(7 answers)
Chrome Extension Message passing: response not sent
(3 answers)
Closed 1 year ago.
This is in a background script.
Everything seems to work down to the result, but my list variable seems to be empty no matter where I declare it in the scope. How do I use sendResponse to get the data back to my content script? What am I missing?
chrome.runtime.onMessage.addListener(
function (request, sender, sendResponse) {
list = [];
// list available channels
if (request.action.includes("channels")) {
function inContent() {
let elems = document.getElementsByClassName("name-sec");
let channelsList = [];
for (let ii = 0; ii < elems.length; ii++) {
let channel = elems[ii];
channelsList.push(channel.innerText);
}
return channelsList;
}
chrome.tabs.executeScript({ code: `(${inContent})()` }, function (result) {
list = result[0];
});
// list is empty
sendResponse({action: `Channels List:${"\n"}${list.join("\n")}`})
}
}
);
chrome API executes its callbacks asynchronously. Using an asynchronously-invoked callback doesn't run it immediately, it's similar to registering a one-time listener for the 'load' event and then the next statement starts running (calling sendResponse in your case) and uses the current value of list i.e. [].
The solution is two-fold:
wait for the asynchronous callback;
tell onMessage to keep the channel open.
if (...) {
chrome.tabs.executeScript({ code: `(${inContent})()` }, function (result) {
list = result[0];
sendResponse({action: `Channels List:${"\n"}${list.join("\n")}`});
});
return true;
}

Code execution does not wait for value returned [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 4 years ago.
I have following controller and code execution does not wait for the function to bring back values. So some lines of code fail as they are still undefined. How to make sure line execution is in sync.
Also Note: caller function is inside a for loop.
A Controller.js
for (var i=0; i< parseObj.length; i++){
callerFunc: function() {
vc._getValues(A, B, C).then(function (data) {
var vendorNo = data.vendorNo;
var vendorName = data.vendorName
});
// lines of code
}
_getValues: function(A, B, C){
var filters = [
.....
];
var vc = this;
return new Promise(function (resolve, reject) {
service.getDataByFilters(vc, filters,
function (data) {
resolve(data);
},
function (error) {
reject();
}
);
});
the problem is that you need to wait for the result. Service.getMaterial is returning a Promise so when you try to execute the line of code var x = data.Vendor; the variable data is not yet defined.
What you can do is to just call a function inside the promise result (the then function).
I would suggest you learn a little bit more about:
Promise
async/await pattern
I also would like you to know that promise/async-await are not supported by IE in general if I'm not wrong ;)

Get the result to use for loop [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 7 years ago.
I have a function and a loop:
var songs = Musics.searchSongs(query).then(function(rs) {
return rs;
});
for (var i = 0; i < songs.length; i++) {
console.log(songs[i]);
}
Now I want to run the loop with the result that taken from after executing the function. How can I do that?
You cannot return from an asynchronous call. You can, however, pass in a callback function to an asynchronous call, and pass the result of the call to that callback function.
So, in your case, you could create a function that receives an array of songs, and loops through each song, logging each to the console. You would then pass that function as a parameter to your asynchronous call.
function callback(songs) {
for (var i = 0; i < songs.length; i++) {
console.log(songs[i]);
}
};
Musics.searchSongs(query, callback).then(function(rs) {
callback(rs);
};

How to return data from JQuery GET [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 9 years ago.
I made a function that runs a get request using JQuery.
But I need the get to return this received value to the calling function. function
gettime() {
var timeOut =0;
$.get("http://localhost:8080/t.html", function( data )
{
timeOut = data*1000;
return timeOut;
});
//retun(timeOut);
}
I want the value received by get to be returned to the main function that calls gettime()
please help out.
It's a integer am passing.
An idea could be implementing a callback:
function gettime(callback) {
var timeOut =0;
$.get("http://localhost:8080/t.html", function(data)
{
timeOut = data*1000;
callback(timeOut);
});
}
//Then you can retrieve that value by doing this:
gettime(function(timeout){
//Do your stuff here.
});

Calling for a function returns 'undefined' [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 9 years ago.
I have a form on my page. When the user hits the Send button, in the background it also generates a unique_number by calling for a function that generates this number and also checks in the DB that this number doesn't exist; if it does - generates it again, if doesn't - returns this number. However, for some reason when I'm trying to print out this number to the page, or alert it - I'm getting undefined, though the function returns the number.
Here's the call for the function:
var unique_num = create_unique_number();
alert(unique_num);
rest of this function...
And here's the function itself:
function create_unique_number()
{
var num = Math.floor(Math.random() * (999999 - 100000 + 1)) + 100000;
$.getJSON("inc/API.php",
{
command:"is_unique_number_exist",
unique_num:num
},
function(result){
if(result==true){
create_unique_number();
}
else
{
return num;
}
});
}
I do get the results, if it's true - it generates new number, if false - should return. I tried to alert the num in the else part, and it did Alert the number, but on return - undefined.
Why is it happening and how to fix it?
For a solution using deferred objects, try this:
function create_unique_number()
{
var num = Math.floor(Math.random() * (999999 - 100000 + 1)) + 100000;
return $.getJSON("inc/API.php", {
command:"is_unique_number_exist",
unique_num:num
}).then(function(result) {
return result ? create_unique_number() : num;
});
}
This is of course untested as I don't have your API available, but the theory is that if result is true the .then call returns the result of a recursive call back to the same function. If result is false then it returns the chosen number as the (resolved) result of a new promise.
If any AJAX call fails, the loop should break and you can trap that with a .fail call:
create_unique_number().done(function(n) {
// use your unique number "n" here
var unique_num = n;
...
}).fail(function() {
// there was an AJAX error
});
// can't use "unique_num" here - execution continues here immediately
// and "unique_num" isn't defined until the above ".done" callback is
// invoked some time later
Note that the recursive call isn't truly recursive - since AJAX is event driven, the original function will already have terminated and cleaned up its stack long before the AJAX .then event fires. The resulting new call to create_unique_number will be at the same "call stack" level as the original call.
Also, as pointed out in the comments, it would actually be far simpler to have the server give you a random number.

Categories

Resources