The argument must be a function [duplicate] - javascript

This question already has answers here:
setTimeout - callback argument must be a function
(4 answers)
Closed 3 years ago.
I want to make a loop that downloads a file on an interval. But I can't make the setTimeout function work when the request function needs a parameter. It's the last line of the progam that i failing. What am I doing wrong?
const http = require('http');
const fs = require('fs');
const file = fs.createWriteStream("file.jpg");
const fileToDownload = "http://i3.ytimg.com/vi/J---aiyznGQ/mqdefault.jpg";
function request1() {
http.get(fileToDownload, function(response) {
response.pipe(file)
});
}
function request2(saveName) {
const save = fs.createWriteStream(saveName);
http.get(fileToDownload, function(response) {
response.pipe(save)
});
}
setTimeout(request1, 3000);
setTimeout(request2("file2.jpg"), 3000); // TypeError: "callback" argument must be a function

You're not passing a function, rather its result.
Use the following instead:
setTimeout(() => request2("file2.jpg"), 3000);

Instead of passing a function to the setTimeout as it expects, you're passing a function call, which will take the parameter as the return type of the function instead of the function itself.
Instead you can just pass a function like -
setTimeout(() => request2("file2.jpg"), 3000);

Instead of calling function directly, try this:
setTimeout(function(){
request2("file2.jpg")
}, 3000);
Or using arrow function
setTimeout(() => request2("file2.jpg"), 3000)

Related

NodeJS: Assign the value inside a callback function to a variable outside of it [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)
Closed 1 year ago.
I want to assign the value inside a callback function to a variable outside of it. Here is an example with child_process.
callback.js
let variable;
require('child_process').spawn('python', ['./hello.py']).stdout.on('data', data => {
variable = data.toString();
console.log(variable);
});
console.log(variable);
hello.py
print('Hello World')
output:
undefined
Hello World
I know that the console.log at the bottom is being executed before the callback function and therefore the variable is still undefined. But how could I wait for the callback function to finish first?
Solution:
Promises seem to be the optimal answer and the code needs to be asynchronous.
async function test() {
const promise = new Promise((resolve, reject) => {
require('child_process').spawn('python', ['./test.py']).stdout.on('data', data => {
resolve(data.toString());
});
});
return promise;
}
(async function () {
let variable;
await test().then(res => {
variable = res;
});
console.log(variable);
}())
You can use a promise to wait for the callback like in this example:
let data;
const myPromise = new Promise((resolve, reject) => {
setTimeout(() => {
data="abc";
resolve('foo');
}, 300);
});
myPromise.then((res)=>{console.log(data+res)})
this will print out "abcfoo"
Often the best way to wait for something asynchronous is to have asynchronous code yourself.

How to run database queries synchronously in javascript [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)
Closed 4 years ago.
let positionSettings = require('setting');
function getSetting(element) {
let setting;
positionSettings.find({element: element}, function (err,docs) {
console.log(docs[0].current); // output the value
setting = docs[0].current;
});
return setting;
}
$(document).on("click", "#save" , function(e) {
console.log(getSetting("abc")); // Output undefined
});
Why is the getSetting() function returning undefined. How can I achieve it.
Because it's an async function, you can't mix async and sync functions this way, try something like this:
let positionSettings = require('setting');
function getSetting(element, callback) {
positionSettings.find({element: element}, (err,docs) => {
let setting;
console.log(docs[0].current); // output the value
setting = docs[0].current;
callback(setting);
});
}
$(document).on("click", "#save" , (e) => {
getSetting("abc", (setting) => {
console.log(setting);
});
});
The fact is that you can't be sure that the data will be avaible after the function call, the only place that you have this sure is inside the callback.
And just a hint, use arrow functions to declare anonymous functions.

beginner asynchronous value passing and returning in javascript [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 6 years ago.
Here is the test for the function I am trying to write.
var chai = require('chai');
var doLater = require('../05-callback');
var expect = chai.expect;
describe('05-callback', function () {
it('Can get secret number', function (done) {
doLater(function (secret) {
expect(secret).to.equal(1337);
done();
});
});
});
I have written code that log's a message to the console asynchronously however, this code does not return the 1337 value asynchronously.
function doLater(secret) {
var code = 1337;
(function setImmediate(code) {
console.log("I will be executed immediately");
return code;
})(code);
setTimeout(function secret(code) {
console.log("I will be executed in 2 seconds.");
return code;
}, 2000);
}
Please let me know if this post is not clear and I will edit it. Forgive me if this post is redundant, the simular post's I found were to advanced for me. Thank you for your help!
In order to do what you want to do, you need to use a callback. Example:
function doLater(callback) {
setTimeout(function(){
//after 2 seconds call the callback
return callback(1337);
}, 2000)
}
//pass as param a function that will be called
doLater(function(result) {
console.log(result) //1337
})

Async function pass data to async function [duplicate]

This question already has answers here:
AngularJS : Where to use promises?
(4 answers)
Closed 7 years ago.
I have the following code:
//calling AsyncFunction
var coords = LocationSerivice.getLocation();
var localStores;
setTimeout(function(){
//works
console.log(coords);
//calling async function again
localStores = LocalStoresService.getLocalStores(coords[0],coords[1]);
}, 100);
setTimeout(function(){
//doesn't work
console.log(localStores);
}, 100);
What am I trying to do is to first call a Async function that returns my location. Then in order to get the data from that function I am setting timeout. With the data received I am calling second Async function. And again I am setting timeout in order to get the data from my second Async function, so here it fails. If I try to display the data with console.log() in the timeout block it says undefined while console.log()in the first timeout block works.
I have tried also increasing the timeout time but it just doesn't work.
Any suggestions how to get over that ?
You could modify your LocalStoresService.getLocalStores method to accept a callback.
function getLocalStores (arg1, arg2, cb) {
// do stuff.
var localStores = 'w/e';
if (typeof cb === 'function') return cb(localStores);
}
So your invoking method would look like this:
var coords = LocationService.getLocation();
LocalStoresService.getLocalStores(coords[0], coords[1], function (localStores) {
console.log(localStores); // 'w/e'
});
It really depends on the type of technology you're using, as the "correct" implementation of async methods can vary from type to type (AngularJS, NodeJS, vanilla JS etc..)
As i understand your project might be using angularjs i am giving example based on that ,
.factory('LocationSerivice', function ($http) {
return{
getLocation : function () {
return $http.get('location_api');
};
getLocalStores : function(coords){
return $http.get('your_local_store_api');
};
}
});
Now call your API's
LocationService.getLocation().success(function(coords){
LocationService.getLocalStores(coords).success(function(localStores){
console.log(localStores);
});
});

Get return value from setTimeout [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 3 years ago.
The community is reviewing whether to reopen this question as of 9 days ago.
I just want to get the return value from setTimeout but what I get is a whole text format of the function?
function x () {
setTimeout(y = function () {
return 'done';
}, 1000);
return y;
}
console.log(x());
You need to use Promises for this. They are available in ES6 but can be polyfilled quite easily:
function x() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('done!');
});
});
}
x().then((done) => {
console.log(done); // --> 'done!'
});
With async/await in ES2017 it becomes nicer if inside an async function:
async function() {
const result = await x();
console.log(result); // --> 'done!';
}
You can't get a return value from the function you pass to setTimeout.
The function that called setTimeout (x in your example) will finish executing and return before the function you pass to setTimeout is even called.
Whatever you want to do with the value you get, you need to do it from the function you pass to setTimeout.
In your example, that would be written as:
function x () {
setTimeout(function () {
console.log("done");
}, 1000);
}
x();
Better to take a callback for function x and whatever task you want to perform after that timeout send in that callback.
function x (callback) {
setTimeout(function () {
callback("done");
}, 1000);
}
x(console.log.bind(console)); //this is special case of console.log
x(alert)
You can use a combination of Promise and setTimeOut like the example below
let f1 = function(){
return new Promise(async function(res,err){
let x=0;
let p = new Promise(function(res,err){
setTimeout(function(){
x= 1;
res(x);
},2000)
})
p.then(function(x){
console.log(x);
res(x);
})
});
}
I think you want have flag to know event occured or no. setTimeout not return a value. you can use a variable to detect event occured or no
var y="notdone";
setTimeout(function () {
y="done";
}, 1000);
You can access variable y after timeout occured to know done or not

Categories

Resources