fabric.loadSVGFromURL when called in a loop always call the last callback - fabricjs

fabric.loadSVGFromURL when called in a loop always call the last callback, and not all the callbacks in the loop.
Looks like a closure issue in fabric loadSVGFromURL. The code below always print value 2 in console log which tells us that the callback is invoked only for the last iteration.
Code
var paths = ['walking-0.svg', 'walking-1.svg', 'walking-2.svg'];
for (var i = 0; i < paths.length; i++) {
var path = paths[i];
fabric.loadSVGFromURL(path, (function (i) {
return function (objects, options) {
console.log(i); //always print 2, when the expected behaviour is to print all the three number starting from 0 to 2.
console.log(objects) //print only once, when it should print thrice
}
})(i));
}

Related

how can call another function after excuted multiple function in loop node js

Please find below code
function get_btc(address) {
address_transaction(address, user_id, coin_key, deposite_txn_fee, function(callback) {
for (var j = 0; j < callback.response.data.txs.length; j++) {
let user_id = callback.user_id;
//some code//
}
});
}
get_label_info(function(err, data) {
for (var i = 0; i < data.length; i++) {
let address = data[i].address;
deposite_model.get_coin_info(function(err, data1) {
var coin_name = data1[0].coin_code;
const return_functions = get_switch(coin_name);
if (return_functions) {
obj[return_functions](address);
}
})
}
});
function all_completed() {
console.log('all functions has been completed');
}
By the help of above mentioned code i want to excecute all_completed loop when all functions has been completly done.
At the initial start get_label_info function is excuted then controller go on to get_btc function.
Please help me how could i run all_completed functions after all functions completed run.
I'll assume you are using es6, and that you know what a Promise is in that context. In that case wrap all your callback based things in a Promise that resolves when the callback completes. Then, in your loop, push all your Promises into an array variable. Finally call Promise.all with that array as an argument and call then on the result to encapsulate the code you want ti run after they all complete (resolve).

nodejs do something after multiple functions complete

I'm having a problem that I can't seem to get around.
Imaging the following
if (users) {
for (var i = 0; i < users.length; i++) {
apiData.users = getUserDetails(users[i]);
}
}
and
if(profiles) {
for (var i = 0; i < profiles.length; i++) {
apiData.profiles = getProfileDetails(users[i]);
}
}
now, only once both of those blocks of code have been completed (i.e. the API calls have returned the results that are required), would I like to do something like this
for (var i = 0; i < users.length; i++) {
saveUserProfile(apiData)
}
Normally I handle a situation like this by wrapping the first block of code in a function that returns a callback and then running the third function afterwards, but how can I do this when there are effectively 2 separate operations happening?
To be clear, I would like to avoid saving users and profiles separately, there are various reasons for this.
I would like to know if there is any standard way of handling a situation like this as there may or may not be users or profiles, so using callbacks seems like it will not work?
You can use async module to achieve this.
Use async.parallel() function since your first and second snippets do not depend on each other, and can run asynchronously, but you wish to make third snippet run when first and second are done executing.
Assuming users, profiles, and apiData are already declared, your code would look like
function func1(callback){
if (users) {
for (var i = 0; i < users.length; i++) {
apiData.users = getUserDetails(users[i]);
}
}
//invoke callback
}
function func2(callback){
if(profiles) {
for (var i = 0; i < profiles.length; i++) {
apiData.profiles = getProfileDetails(users[i]);
}
}
//invoke callback
}
var asyncfunc = [];
asyncfunc.push(func1);
asyncfunc.push(func2);
async.parallel(asyncfunc,function(err,result){
//result is an array which receives the second argument of each function's callback.
for (var i = 0; i < users.length; i++) {
saveUserProfile(apiData)
}
})
EDIT
PS: you can also use async.series() here. Both are equivalent in this case, since the functions handled by async.parallel() here do not use timers neither perform I/O tasks.
The callback in each function inside the array takes two arguments. First argument represents error, which is null if there are no errors, second represents the result of the function, which is passed to the second argument of the async.parallel() function's callback.

Node Js getting an issue while executing for loop

I am using node js to develop my application. In controller i used a for loop and then wrote some code, but in for loop i am executing a query. So before that query completely executed once the code after for loop executing. See below for example.
var commcount = [];
for (var j = 0, len = exlist.length; j < len; j++) {
console.log('exlist[j].id '+exlist[j].id);
ExModel.find({EXModel_ID:exlist[j].id, VALUE: {'$ne':''}},{_id:0}, {sort: {CREATION_DATE: -1}}, function(err1, examplist) {
if (err1) {
console.log('sub error '+err1);
commcount.push(0);
} else {
console.log('examplist.length '+examplist.length);
commcount.push(examplist.length);
}
});
}
console.log('commcount length '+commcount.length);
In above code let us assume exlist.length is 5 so, for loop will be executed for 5 times. In the output console, First exlist[j].id value displaying all 5 times then commcount length value displaying as 0 then only examplist.length value diplaying. So before query executed the for loop for other statements and statements after for loop are being executed. Please help me to solve this. I want the length of result list of query in for loop to be stored in array and want to display those array values after for loop.
First of all you should know that you are calling asynchronous function, whatever the result you are getting is correct, The asynchronous function will run in separate thread, we can not guarantee the out put. Your code is similar to the below code, Let's run the below code
function run(){
console.log("d");
setTimeout(function(){
console.log("a");
setTimeout(function(){
console.log("b");
});
});
console.log("c");
}
The output will be d c a b.

Get the result at the right time with node

i am new to node.js, i followed some tutorial.
I don't know how to get the array "result" only when the call in the function end.
app.get('/api/email/check/:email',function (request,response){
var email = request.params['email'];
var result = Array();
for (var i = 0; i < 2; i++) {
existence.check(email, function(err,res){
result[i]=res; console.log({"Result":res});
});
};
response.send(result); // Problem is that i get: []
});
I got the log but the result is an empty array because it's called before the functions ends. Is there a nice way to resolve this ? without counting the "i".
You can put
response.send(result);
out of the for loop.
Because response.send() is a async method so before the for loop ends, response has ended before.

Declared array returning undefined

In my project, one of the functions should update a list of users with new stats,and I have that function:
function gameEnded(team){
//reset variables
playersObject = {};
isPlaying = false;
subQueue = {};
subArray = [];
blueList = ["Jonas","LucasTT"];
redList = ["Lucas","Manelzao"];
//updates database
for(i=0; i<blueList.length; i++){
getPlayerStats(blueList[i], function(oldStats){
console.log(blueList[i]);
setPlayerStats(blueList[i], [oldStats[0]+6,oldStats[1]]);
});
}
}
It should get the a name from the list, get the name's stats(using MySQL),and then update it. But, the console.log there is logging undefined, but the array is declared. What is causing that to do so?
The problem is that the callback doesn't run until after that loop has finished, at which point i is equal to blueList.length, and in javascript indexing past the end of an array returns undefined.
You'll want to freeze the value of i in each iteration of the loop, which can be done with an IIFE:
for(i=0; i<blueList.length; i++){
(function(i) {
getPlayerStats(blueList[i], function(oldStats){
console.log(blueList[i]);
setPlayerStats(blueList[i], [oldStats[0]+6,oldStats[1]]);
});
})(i);
}

Resources