Javascript callback function not work - javascript

I'm working with nodeJS and expressJS. I Have 2 functions,
main functions:
download(imgUrl, imgMD5, function(fileLength, fileSize) {
console.log(fileLength);
var qb = data.Img.query();
qb.where('img_md5', '=', imgMD5).update({
img_downloaded: 1
}).then(function() {});
});
and external function
module.exports = function() {
return function(uri, filename) {
request(uri, function(err, res, callback) {
fileLength = res.headers['content-length'];
var mkdirs = function(fold, callback) {
var pf = path.dirname(fold);
fs.exists(pf, function(exists) {
var create = function() {
fs.mkdir(fold, callback);
};
if (exists) {
create();
} else
mkdirs(pf, create);
})
};
var folder = ('./downloaded/' + yy + '/' + mm + '/' + dd + '/' + ho + '/');
mkdirs(folder, function() {
var r = request(uri).pipe(fs.createWriteStream(folder + filename));
r.on('close');
});
callback(fileLength);
});
};
};
but it's fired an error when running:
TypeError: string is not a function
I don't know if I'm uses the callback right or not?
thank you

Your request() callback parameters aren't quite labelled appropriately. The third argument passed to your callback is the entire buffered (string) body from the response, not a function. So that's why it complains at callback(fileLength);.
Also, because you used a callback (which receives the entire buffered response), there is no need to request the URL again. So you could change this:
mkdirs(folder, function(){
var r = request(uri).pipe(fs.createWriteStream(folder + filename));
r.on('close');
});
to this:
mkdirs(folder, function() {
// `data` here is the third argument to the `request()` callback ...
fs.writeFile(folder + filename, data);
});
to save an extra HTTP request.
Or if you really do want to stream the response data, you could do:
request(uri).on('response', function(res) {
// ...
mkdirs(folder, function() {
res.pipe(fs.createWriteStream(folder + filename));
});
});

Related

Callback function not receiving data after function returns data from API endpoint

On-Click Function
$(".action-open-instruction-confirm").on("click",
function(event) {
var applicationNumber = $('.case-application-number').val();
getInstructionType(applicationNumber, function(data) {
$("#InstructionConfirm #instruction-confirm-instruction-type").html(data);
});
});
Endpoint function
function getInstructionType(applicationNumber) {
if (window.location.port !== "") {
port = ":" + window.location.port;
} else {
return null;
}
var url = window.location.protocol +
"//" +
window.location.hostname +
port +
"-apiEndpoint-?applicationNumber=" +
applicationNumber;
$.get(url,
function(data) {
return data; //<-- Change this to $("#InstructionConfirm #instruction-confirm-instruction-type").html(data); and it works correctly
});
}
HTML
<div id="InstructionConfirm">
<span id="instruction-confirm-instruction-type"></span>
</div>
I have the two functions above that I am trying to use to alter the HTML of the `#instruction-confirm-instruction-type element present in my HTML. The problem is that at the moment the callback function doesn't seem to be functioning properly.
The On-Click function passes the applicationNumber to the getInstructionType function which then calls an API endpoint. This endpoint works correctly and returns the data with no issues. However it then seems like the return data; line in my getInstructionType function doesn't seem to be returning the data properly, as the callback function in the on-click is never executed.
I know the callback is not being executed as it doesn't trigger the breakpoint I have on the $("#InstructionConfirm #instruction-confirm-instruction-type").html(data); line.
If I then replace the return data; line in the second function with $("#InstructionConfirm #instruction-confirm-instruction-type").html(data);, then I get the behaviour I am expecting with no issues.
What exactly is preventing getInstructionType from returning the data to my callback function for it to be used within the on-click function?
The issue is because you don't do anything with the callback you provide. You don't create an argument in the function definition for it, and you don't call it from $.get(). Try this:
$(".action-open-instruction-confirm").on("click", function(e) {
var applicationNumber = $('.case-application-number').val();
getInstructionType(applicationNumber, function(data) {
$("#InstructionConfirm #instruction-confirm-instruction-type").html(data);
});
});
function getInstructionType(applicationNumber, callback) { // accept the 'callback' argument
if (window.location.port !== "") {
port = ":" + window.location.port;
} else {
return null;
}
var url = window.location.protocol + "//" + window.location.hostname + port + "-apiEndpoint-?applicationNumber=" + applicationNumber;
$.get(url, callback); // invoke the callback when $.get receives data
}
Also note that you can just use location.origin instead of manually building the protocol/domain/port string:
var url = window.location.origin + "-apiEndpoint-?applicationNumber=" + applicationNumber;
Although it looks like you may be missing a / after the port as your URL will currently include the string after the port which appears to be incorrect.
Your function doesn't have a parameter for the callback:
function getInstructionType(applicationNumber) {
should be:
function getInstructionType(applicationNumber, callback) {
you can then add your callback
$.get(url,
function(data) {
if ($.isFunction(callback))
callback(data);
});
or even just:
$.get(url, callback)
You might like to consider using promises instead, eg:
$(".action-open-instruction-confirm").on("click",
function(event) {
var applicationNumber = $('.case-application-number').val();
getInstructionType(applicationNumber).done(function(data) {
$("#InstructionConfirm #instruction-confirm-instruction-type").html(data);
});
});
function getInstructionType(applicationNumber) {
....
return $.get(url);

Identify the caller (or how pass parameter) of a callback (JSON) function in JavaScript

When i request
BASE_URL + 'json/valueone?callback=fnCallBack0'
the response from server is treated in a callback function. This function receives (ASYNCHRONOUS) data (JSON format) but do not include the initial parameter "valueone"
var BASE_URL = ...
function fnCallBack(data){
if (data != null) {
// HERE...I NEED ID <====================
// arguments.callee.caller <==================== dont work
console.log('information', data);
}
}
// onclick callback function.
function OnClick(info, tab) {
var arrH = ['valueone', 'valuetwo'];
arrH.forEach(function(value) {
var scrCallBack = document.createElement('script');
scrCallBack.src = BASE_URL + 'json/' + value + '?callback=fnCallBack';
//BASE_URL + 'json/one?callback=fnCallBack0';
document.body.appendChild(scrCallBack);
});
My solution is to create an intermediate function correlative name (fnCallBack0, fnCallBack1, ...), a global array, and a counter. Works fine, but this is not OOP, is a fudge.
var BASE_URL = ...
//global array
var arrH = [];
var fnCallBack0 = function(data){
fnCallBack(data, '0');
}
var fnCallBack1 = function(data){
fnCallBack(data, '1');
}
function fnCallBack(data, id){
if (data != null) {
console.log('information', data + arrH[id]);
}
}
// onclick callback function.
function OnClick(info, tab) {
var i = 0;
arrH = ['valueone', 'valuetwo'];
arrH.forEach(function(value) {
var scrCallBack = document.createElement('script');
scrCallBack.src = BASE_URL + 'json/' + value + '?callback=fnCallBack' + (i++).toString();
//BASE_URL + 'json/one?callback=fnCallBack0';
document.body.appendChild(scrCallBack);
});
chrome.contextMenus.create({
title: '%s',
contexts: ["selection"],
onclick: function(info) {console.log(info.selectionText)}
});
var idConsole = chrome.contextMenus.create({
title: 'console',
contexts: ["selection"],
onclick: OnClick
});
I tried with inject function as code in html page, but i receeived "inline security error", and a lot of similar questions.
Please, NO AJAX and no jQuery.
This is my first post and my first chrome extension
Thanks in advanced.
I don't see how anything of this has to do with OOP, but a solution would be to just create the callback function dynamically so that you can use a closure to pass the correct data:
function fnCallBack(data, value){
if (data != null) {
console.log('information', data + value);
}
}
// onclick callback function.
function OnClick(info, tab) {
['valueone', 'valuetwo'].forEach(function(value, index) {
// unique function name
var functionName = 'fnCallback' + index + Date.now();
window[functionName] = function(data) {
fnCallBack(data, value);
delete window[functionName]; // clean up
};
var scrCallBack = document.createElement('script');
scrCallBack.src = BASE_URL + 'json/' + value + '?callback=' + functionName;
document.body.appendChild(scrCallBack);
});
}

NodeJS return http.request

Hi now I know that NodeJS is asynchronous (which I am still trying to get my head around to be honest).
The problem that I am currently facing is I have attempting to do a http.request to receive some JSON data. This is fine but what I need is to return this data to a variable. I believe I need to do a callback function? (from what I have read up on the matter)
The Code that I currently have:
var http = require('http');
pCLatLng = '';
function postCodeCheck() {
var pCode = {
host: 'geo.jamiethompson.co.uk',
path: "/" + 'SW1A2AA' + ".json"
};
http.request(pCode).on('response', function(response) {
var data = '';
response.on("data", function (chunk) {
data += chunk;
});
response.on('end', function () {
pCJSON = JSON.parse(data);
pCLatLng = pCJSON;
});
}).end();
}
console.log(pCLatLng);
This is obviously outputting "undefined"; I have tried returning the response.on('end') when having return "hi" or anything inside it instead NodeJS outputs the information about the site. If anyone can help with this it would be much appreciated.
console.log(pCLatLng); needs to be inside (or inside something called by) the response.on('end' callback. The value isn't available until that callback is fired.
Try something like:
function postCodeCheck(callback) {
var pCode = {
host: 'geo.jamiethompson.co.uk',
path: "/" + 'SW1A2AA' + ".json"
};
http.request(pCode).on('response', function(response) {
var data = '';
response.on("data", function (chunk) {
data += chunk;
});
response.on('end', function () {
callback(JSON.parse(data));
});
}).end();
}
postCodeCheck(function (pCLatLng)
{
console.log(pCLatLng);
});
You want something like this:
var http = require('http');
function postCodeCheck(cb) {
var pCode = {
host: 'geo.jamiethompson.co.uk',
path: "/" + 'SW1A2AA' + ".json"
};
http.request(pCode).on('response', function(response) {
var data = '';
response.on("data", function (chunk) {
data += chunk;
});
response.on('end', function () {
var pCJSON = JSON.parse(data);
cb(pCJSON);
});
}).end();
}
postCodeCheck(function(pCLatLng) { console.log(pCLatLng); });
Look carefully for the differences before using.
You'll need your postCodeCheck() function to take a callback as well, just like http.request. In the world of async, calling callbacks with results takes a similar role to returning results.

How to return values from functions making HTTP request in node.js?

The getStockValue() function is called from another javascript file in the following way:
var r=require("./stockfile");
var returedData = r.getStockValue());
here returnedData contains only "-START-".
My objective is to get the body object returned from the function, after receiving the response. I've tried putting a return statement into the 'close' event handler, but it didn't work.
How should I do that?
function getStockValue() {
var http = require('http');
var options = {
host: 'in.reuters.com',
path: '/finance/stocks/overview?symbol=RIBA.BO',
method: 'GET'
};
var body = "--START--";
var req = http.request(options, function (res) {
console.log('STATUS: ' + res.statusCode);
console.log('HEADERS: ' + JSON.stringify(res.headers));
res.on('data', function (chunk) {
body += chunk;
});
res.on('close', function () {
console.log("\n\nClose received!");
});
});
req.on('error', function (e) {
console.log('problem with request: ' + e.message);
});
req.end();
return body + '... recieved';
}
exports.getStockValue = getStockValue;
As this is an asynchronous operation if will return straight away and continue to run in the background, hense why you only receive -START-. You can resolve this with the help of a callback function. Heres how:
Call the function as follows:
r.getStockValue(function(result) {
var returedData = result
//... rest of your processing here
}));
and within the getStockValue function change to this:
function getStockValue(callback) {
...
res.on('data', function (chunk) {
body += chunk;
callback(body);
});
...
}

How to use YQL in JavaScript to retrieve web results

I have been trying the code given in
How to use YQL to retrieve web results?
but it is not working.
Please suggest me something else or rectify that code.
I am just calling a function on page_load
<body onload = "load_content();">
In the load_content() method, I have to get the feed of other web site and display it on my HTML page.
Load_Content method
var query = "select * from html where url='http://www.imdb.com/title/tt0123865/'";
// Define your callback:
var callback = function(data) {
console.log("DATA : " + data);
};
// Instantiate with the query:
var firstFeedItem = new YQLQuery(query, callback);
// If you're ready then go:
console.log("FEED : " + firstFeedItem.fetch()); // Go!!
Function YQLQuery
function YQLQuery(query, callback)
{
this.query = query;
this.callback = callback || function(){};
this.fetch = function() {
if (!this.query || !this.callback) {
throw new Error('YQLQuery.fetch(): Parameters may be undefined');
}
var scriptEl = document.createElement('script'),
uid = 'yql' + +new Date(),
encodedQuery = encodeURIComponent(this.query.toLowerCase()),
instance = this;
YQLQuery[uid] = function(json) {
instance.callback(json);
delete YQLQuery[uid];
document.body.removeChild(scriptEl);
};
scriptEl.src = 'http://query.yahooapis.com/v1/public/yql?q='
+ encodedQuery + '&format=json&callback=YQLQuery.' + uid;
document.body.appendChild(scriptEl);
};
}
Nothing is coming in data variable
A simple get request is an answer to this.
$.get("http://www.imdb.com/title/tt1243957/",
function(data){
console.log(data);
}//end function(data)
);//end getJSON

Categories

Resources