Calling a JavaScript function from shiny server - javascript

I want to call a javascript function, display in my case, from server.R with one parameter. The print statement below the call is getting executed, but the javascript function is not getting executed. Is this the right way of calling js function?
observe ({
if (is.null(input$location))
return()
tags$script(type="text/javascript", src = "datadisplay.js")
tags$script(JS('display(today_trends))'))
print(today_trends[1])
})
}
My js file:
function disp(params) {
var myWindow = window.open("");
myWindow.document.write("New window");
}
I've also tried js$display(today_trends) this way, but I get an error: Attempt to apply non-function.
Modified js file:
shinyjs.display = function(params) {
var myWindow = window.open("");
myWindow.document.write("New window");
};

Related

Accessing an Immediately Invoked Function Expression variable in Node.js in another file using require

File 1 - Monitor.js
var MONITOR = (function () {
// File Content
return {
doThing: function() {
doThing();
}
};
})();
File 2 - Test.js
var monitor = require('../public/js/monitor.js');
I want to access doThing() in File 2. I have tried various syntax and no luck so far.
From the frontend HTML I can simply include Monitor.js in a script tag, and call MONITOR.doThing(); without trouble but in Test.js this is proving difficult.
Any advice on how?
You have to export MONITOR so that someone else can access it with require().
Add this:
module.exports = MONITOR;
at the bottom of Monitor.js.
And, if you want the monitor.doThing() method to return some value, then you have to add a return statement to the function as in:
var MONITOR = (function () {
// File Content
return {
doThing: function() {
return "hello";
}
};
})();

Can't call a global function

Writing a unit test for Apigee JS policy.
I am trying to call context.getVariable("env") from send Msg ()
but context is not recognized as a global and hence I cant callcontext.getVariable().
edit: I cant add global.context.getVariable("env") as it is an Object of Apigee's platform
global.context={}
global.context.getVariable=function(){}
function logger(){
function log(msg){
this.sendMsg(msg)
}
var sendMsg = function (){
context.getVariable("env")
}
return {
log:log,
sendMsg:sendMsg
}
}
logger().sendMsg()//TypeError: context.getVariable is not a function
Why is it happening? and what should I do?
I have tried calling
logger().sendMsg.apply(global) is that ok?

How to access functions in injected .js files from evaluate()?

Is it possible to reference functions in an embedded JavaScript file, when calling page.evaluate() using PhantomJS?
e.g. I would like to call a function someFunctionInMyJs included in the file my.js:
var page = require('webpage').create();
page.injectJs('my.js')
page.open('http://...', function() {
var x = page.evaluate(function() {
var y = someFunctionInMyJs();
return y;
});
phantom.exit();
});
Is that possible/are there alternative approaches?
my.js looks like this:
function someFunctionInMyJs() {
return 'Hi there!';
}
and the error I'm getting is:
ReferenceError: Can't find variable: someFunctionInMyJs
my.js lies in the folder where I'm invoking PhantomJS.
The problem is that you inject a script into the page which is about:blank at this point and then open your intended page. You need to inject your script inside of the page.open callback. You will have to do this every time you navigate to another page.
page.open('http://...', function() {
page.injectJs('my.js')
var x = page.evaluate(function() {
var y = someFunctionInMyJs();
return y;
});
phantom.exit();
});
You can also try to inject (injectJs) your script from through the page.onInitialized handler, if your script for example exchanges the implementation of XMLHttpRequest.
If this still doesn't work, it is possible that your function isn't global in which case you have to make it so. Edit my.js to define your function as
window.someFunctionInMyJs = function() {
return 'Hi there!';
};

probably moronic js syntax error. Object is null

var fbToggle = document.getElementById("fbToggle");
and later in the script
fbToggle.addEventListener("click", toggle("fbContainer"));
Console tells me that fbToggle is NULL
This is in the document though.
<input type="checkbox" id="fbToggle">
I wasnt using eventListener before, so maybe there is a special order of declaration i'm missing ?
EDIT :
entire js :
function toggle(target) {
var obj = document.getElementById(target);
display = obj.style.display;
if (display == "none") {display = "block"}
else {display = "none"}
}
function init() {
var fbToggle = document.getElementById("fbToggle");
var twitToggle = document.getElementById("twitToggle");
var pinToggle = document.getElementById("pinToggle");
console.log(fbToggle); // NULL
fbToggle.addEventListener("click", toggle("fbContainer"));
twitToggle.addEventListener("click", toggle("twitContainer"));
pinToggle.addEventListener("click", toggle("pinContainer"));
}
window.onload = init();
HTML is way too long.but JS is in head, called from external file. Also i'm not in quirk mode.
It is not clear where "later in the script" is. If it is in different scope definitely it is not going to work. Suggesting you to keep everything in a global object if possible so that you can access from different places in the script.
window.globals = {};
window.globals.fbToggle = document.getElementById("fbToggle");
window.globals.fbToggle.addEventListener("click", function () {
toggle("fbContainer")
});
function toggle(container) {
alert(container);
}
http://jsfiddle.net/ST938/
Another point is addEventListener expects a function or function idenitifier, NOT a function call.
addEventListener("click", toggle("fbContainer")); // wrong
addEventListener("click", toggle); // correct
So if you want to pass a parameter
window.globals.fbToggle.addEventListener("click", function () {
toggle("fbContainer")
});
function toggle(container) {
alert(container);
}
In JavaScript, putting brackets after a function name causes it to be called. If you want to reference a function without calling it you must not put brackets after the name:
window.onload = init(); // this calls init() immediately
window.onload = init; // this correctly stores init in window.onload
The same applies to toggle(). If you need to pre-specify some of the arguments you can wrap it in an anonymous function:
fbToggle.addEventListener("click", function() { toggle("fbContainer"); });
or you can use bind:
fbToggle.addEventListener("click", toggle.bind(null, "fbContainer"));

Illegal Invocation jQuery HTML5 Audio Play

Background
Basically, this code takes all of the audio tags on the page, and when one finishes it starts the next one in the DOM.
The Issue
When fnPlay is called I receive an Illegal Invocation error.
//THIS CODE FAILS
var lastAudio = null;
$('audio').each(function(index) {
var fnPlay = $(this)[0].play;
if (lastAudio != null) {
lastAudio.bind("ended", function() {
fnPlay();
});
}
lastAudio = $(this);
});
Now I am sure that the rest of the code is fine, because the following worked.
//WORKS GREAT!
var lastAudio = null;
$('audio').each(function(index) {
var lastAudioObj = $(this)[0];
if (lastAudio != null) {
lastAudio.bind("ended", function() {
lastAudioObj.play();
});
}
lastAudio = $(this);
});
Question
Can anybody explain why I couldn't store the play() function inside my variable fnPlay and call fnPlay(), but I could store the object and call the play() function on the object?
This is because of how the context of JavaScript functions work. The context (or this) inside a function is set when it's ran, not when it's set.
When you call lastAudioObj.play();, the play() function is called in the context of lastAudioObj. Inside play(), this is lastAudioObj, so everything works.
When you do fnPlay() however, it has no context. this inside the function will be null (or window). play() doesn't like that, so it throws an exception.
There are a few ways to fix this.
One is to call the function with .call() to manually set the context.
Set the variables like:
var lastAudioObj = $(this)[0];
var fnPlay = lastAudioObj.play;
Then call:
fnPlay.call(lastAudioObj);
You can also use .bind() to set the context when setting the variable.
var lastAudioObj = $(this)[0];
var fnPlay = lastAudioObj.play.bind(lastAudioObj);
Then you can just call it like:
fnPlay();

Categories

Resources