How to pass the variable from outside to onResourceRequested function?
I am not able to access the variable testvar inside the callback function of onResourceRequested property.
Any idea how to fix this issue?
Below is the sample code I used for testing
var phantom = require("phantom");
var _ph, _page, _outObj;
phantom.create().then(function(ph){
_ph = ph;
return _ph.createPage();
}).then(function(page){
_page = page;
var testvar = "WHY THIS IS NOT PRINTING";
_page.property('onResourceRequested', function (req, networkRequest) {
console.log("THIS LINE WORKS");
console.log(testvar); // THIS DOESNT WORK
});
_page.property('onResourceReceived', function (res) {
//console.log('received: ' + JSON.stringify(res, undefined, 4));
});
return _page.open('https://www.ammaus.com/', function (status) {
if (status !== 'success') {
console.log('FAIL to load the address');
}
_ph.exit();
});
}).then(function(status){
console.log(status);
return _page.property('content')
}).then(function(content){
_page.close();
_ph.exit();
}).catch(function(e){
console.log(e);
});
Use arrow function (ES6) like this:
_page.property('onResourceRequested', (req, networkRequest) => {
console.log("THIS LINE WORKS");
console.log(testvar); // THIS DOESNT WORK
});
An arrow function does not newly define its own this when it's being executed in the global context; instead, the this value of the enclosing execution context is used, equivalent to treating this as closure value.
Related
I have a function handler:
function handler(data) {
console.log(`1. ${data}`);
}
which I want to append, or redefine, in the same scope as follows:
let oldHandler = handler;
function handler(data) {
oldHandler(data);
console.log(`2. ${data}`);
}
such that when I now call handler:
handler("bar");
I expect the output to be:
1. bar
2. bar
Is this possible?
EDIT
Currently the above results in error: unknown: Identifier 'handler' has already been declared.
Function declarations:
Declare a variable with a matching name
Are hoisted
Use a function expression instead. These do neither of the above.
function handler(data) {
console.log(`1. ${data}`);
}
let oldHandler = handler;
handler = function handler(data) {
oldHandler(data);
console.log(`2. ${data}`);
};
handler("bar");
I dont know what is the problem with my code.
// emitter.js
var EventEmitter = require('events').EventEmitter;
var util = require('util');
function Loadfun(param1, param2, db){
function __error(error, row){
if(error){
this.emit('error', error);
return true;
}
if(row.length < 1)
this.emit('failure');
}
function doSomething(){
db.query('select something', callback);
}
function callback(err, result){
if(__error(error))
return false;
else
this.emit('success', result);
}
this.doSomething = doSomething;
};
util.inherits(Loadfun,EventEmitter);
module.exports = Loadfun;
This is the emitter function.
and i am using this for some sync db works.
the following is the calling function.
var emitter = require('emitter');
router('/fetch', function(req, res){
var fetch = new emitter(param1, param2, db);
fetch.on('failure', function(){
console.log('error');
});
fetch.on('success', function(data){
console.log(JSON.stringify(data));
});
fetch.doSomething();
});
this works perfectly fine without any errors.
I tried logging the flow till the emiting of success
but the catching of the event emitting is not getting logged..
I dont understand what is the problem.. It would be nice if someone could help.
2 things that I can quickly see are:
You are passing an error if(__error(error)) which is not defined there.
You are calling this.emit in the callback function scope and it is pointing to the db.query and not the EventEmitter
You have to bind this to your callback.
Doing the following will work for you db.query('select something', callback.bind(this));
But you also have to fix your "error" mentioned in number one.
In most of your code, you are using the keyword thisin the wrong context. Every function declared with the function keyword, has its own this context, so when inside __error for example, the thisyou are referring to is not the LoadFun this and so it is not the class extending the EventEmitter class therefore does not emit anything.
You can either bind your functions when calling them, or use arrow functions, or assign to another variable, example with assigning this to another variable :
function Loadfun(param1, param2, db){
var self = this;
function __error(error, row){
if(error){
self.emit('error', error);
return true;
}
if(row.length < 1)
self.emit('failure');
}
function doSomething(){
db.query('select something', callback);
}
function callback(err, result){
if(__error(err))
return false;
else
self.emit('success', result);
}
self.doSomething = doSomething;
};
Can function be executed after some variable got value (or changed) in JavaScript?
In my example, the variable is hoisted at first which is declared to be a global, then will assign some value to it in getData() function.
I have tried using .delay() method, but i don't know how much time the ajax needs.
briefly describe:
1) Declaring variable
2) calling getData() function, then assign the data to variable
3) calling funcA() function
4) calling funcB() function and pass function doSomething() as a callback in funcA()
5) calling the callback function in funcB()
6) log the data in doSomething()
<script>
var variable;
variable = getData();
funcA();
function funcA() {
funcB(doSomething);
function doSomething(data) {
console.log(data);
}
}
function funcB(callback) {
if (variable !== undefined) {//it is obviously undefined.
callback(variable);
}
}
</script>
//another js file
<script>
function getData() {
//get data by using ajax
//i don't know how much time it needs.
return data;
}
</script>
change your getdata to this:
function getData() {
$.ajax({
url: "some url",
success: function(result){
variable = result;
//do everything that should be done here or call your callback
});
}
i have a load(callback) function which takes a callback function as parameter. Can this callback function access variables present in its parent function i.e. load()
(function load(callback)
{
return $.get("../somepage.aspx", {data:data}, function (response, status, xhr){
var x = 10;
if(typeof callback === 'function') { callback(); }
}
})(done);
var done = function(){
//do something with x here
alert(x);
}
You cannot access x like you want because it is outside the scope of the done function.
You need to pass x to the callback:
(function load(callback)
{
return $.get("../somepage.aspx", {data:data}, function (response, status, xhr){
var x = 10;
if(typeof callback === 'function') { callback(x); }
}
})(done);
var done = function(x){
//do something with x here
alert(x);
}
I suspect this is what you want but to but I am taking a stab in the dark here seeing as how the code in the question has serious syntax problems (i.e. done is not a child of parent.)
Nope, it can't because the callback's scope is totally outside the calling scope. Pass x as a parameter in the callback.
I have written the code
// Handlers
function successHandlerFactory (savedFlag) {
return function (res, savedFlag){
if (res.data && res.status == 200) {
ngcoupon_offerManager.addOffers(res.data.offers, -1, savedFlag);
console.log('offers response', res, 'savedFlag', savedFlag);
} else {
console.error('something is wrong to get offers', res);
}
}
};
var offerSuccessHandler = function() {
return successHandlerFactory();
}();
var savedofferSuccessHandler = function () {
return successHandlerFactory(true);
}();
but apparently its giving out savedFlag undefined every executinon I make.
How come this does not work
The issue is in this part of the code:
function successHandlerFactory (savedFlag) {
return function (res, savedFlag){
...
You're re-declaring savedFlag in the inner function, which ends up being the variable that is captured in the success handler. Try simply removing the second parameter of the returned function.