Having eval() recognize the VueJS eventBus - javascript

I'm trying to get eval() to recognize the VueJS eventBus when being called.
Here's an example of the code I'm trying to evaluate:
eval("eventBus.$emit('eventName');");
But I'm getting the error "eventBus is not defined, despite the eventBus being imported and working outside of the eval function.
Is there anyway to set the scope of eval to that of the Vue instance so eventBus is recognized?
Any help would be appreciated! Thank you!
More Information
In my project I'm using Blockly, which runs individual block code by processing a string of code set to a block, and calling eval() on it.
this is my runCode method, inside of a VueJS component
.....
runCode: function() {
// Generate JavaScript code and run it.
window.LoopTrap = 1000;
Blockly.JavaScript.INFINITE_LOOP_TRAP =
'if (--window.LoopTrap == 0) throw "Infinite loop.";\n';
var code = Blockly.JavaScript.workspaceToCode(this.workspace);
Blockly.JavaScript.INFINITE_LOOP_TRAP = null;
try {
eval(code); //Eval call here
} catch (e) {
alert(e);
}
},
....
This is a generalized version of setting the code mapped to the block I want to execute.
Blockly.JavaScript['blockName'] = function(block) {
let code = "eventBus.$emit('eventName');";
return code;
};

Related

Vaadin 14 Springboot javascript does not work

I'm trying to develop my first Vaadin 14 application, I'm also using Spring boot framework for it.
I've created a javascript file, I put it into the folder frontend/src with the name of teams.js and I'm trying to import it with #JsModule("src/teams.js"). My root view class looks like this:
#Route("")
#PageTitle("Teams organization store init")
#Slf4j
#JsModule("src/teams.js")
#Tag("TeamsEntry")
public class TeamsEntryView extends VerticalLayout implements BeforeEnterObserver {
public TeamsEntryView() {
initTeams();
}
private void initTeams() {
var ui = UI.getCurrent();
var page = ui.getPage();
log.info("Teams initialization...");
page.executeJs(getTeamsConfig()).toCompletableFuture().whenComplete(((jsonValue, throwable) ->
log.info("Teams initialization completed: {} with throwable {}", jsonValue.toJson(), throwable.getMessage())
));
}
private String getTeamsConfig() {
return """
console.log('ss');
window.initTeams();
console.log('xx');
return true;
""";
}
...
My js file looks like this:
window = {
initTeams: function () {
console.log('initTeams...');
}
}
In this case, I see "ss" in the browser's console, but nothing more.
If I remove the window.initTeams(); line I get "ss" and "xx" as well.
If I declare a simple function in the js file and call it without the "window" class I get similar results.
If I use #Javascript or page.addJavascript("src/teams.js") I get this error when the page loads: "> unexpected character"
If I try to call join() or get() on the completable future the browser freeze.
If I use #Javascript("frontend://src/teams.js") I get some CORS error like if it is trying to download something from the "frontend" host.
I've tried to put the #JsModule on a component instead of my view.. it does not work.
I've tried to put my js file to the root, and to the resources folder.
I could not find any other solution to import and use my js file into vaadin14 with spring boot.
Also, I'm not sure why the browser freeze if I call "join()" on completable future, and also the on the result of it sentToBrowser returns false even if I see the console logs in the browsers log...
Can somebody explain to me how should I do the javascript import, why my current code does not work, and why the "join()" freezes the browser, please?
Thank you in advance!
#Edit
I have also tried with this annotation #JavaScript("./src/teams.js") and a js like this:
function initTeams () {
console.log('initTeams...');
console.log("Teams initialized!")
}
#Edit
Okay so finally I got it working.
The js file has to be under root/src/main/webapp/src folder.
Nor #JavaScript and nor the #JsModule worked for me, so I had to import my js file as:
var ui = UI.getCurrent();
var page = ui.getPage();
page.addJavaScript("src/teams.js");
Then I can call it like window.initTeams() or like initTeams() and both works fine. Altough the completable future below still never executes, and isSentToBrowser() always returns false.
page.executeJs(getTeamsConfig()).toCompletableFuture().whenComplete(((jsonValue, throwable) ->
log.info("Teams initialization completed: {} with throwable {}", jsonValue.toJson(), throwable.getMessage())
));
I must mention if I start the path with '.' like page.addJavaScript(".src/teams.js"); then it does not find the file.
Does anybody have an answer, why the completable future never executes?
The problem is that the following code redefines the window object:
window = {
initTeams: function () {
console.log('initTeams...');
}
}
Did you meant to add a function to the window object? Like so:
window.initTeams = function () {
console.log('initTeams...');
};
If you want to keep code visually similar to yours:
window = {
...window,
{
initTeams: function() {
console.log('initTeams...');
}
}
}
Other options:
window['initTeams'] = function() {...}
Object.assign(window, {initTeams: function() {...}})
Object.defineProperty(window, 'initTeams', {value: function() {console.log('foo')}});
Gotta love JavaScript...
Also, for more knowledge, the code mentioned in your #Edit section could not be called. Calling initTeams() is equivalent to window.initTeams(). The function must exist in the window object. This is why, for example, you see some custom elements defined like customElements.define(...) and window.customElements.define(...).

How to overcome issue of ".. is not a function" while referring to earlier defined function expression in same js file

On accessing function expression in the same file, gives an error of .. "is not a function".
I need this below function expression to be available both outside the js file to other .js files and as well inside the same js file.
I have tried below things from below blogs, nothing seems to work
https://github.com/nodejs/node/issues/2923
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Not_a_function
// this is in abc.js
function qpValidations() {
this.addDaystoGetDate = function(noOfDays){
...
}
this.constructDate = function(){
this.addDaystoGetDate(2);// here issue is coming, where trying to
//call function in same .js file
}
}
module.exports = new qpValidations();
Any help is most appreciated!!, though this issue occurred many times with me, tried avoiding file circular dependency and as well clubbing function expression and declaration, had solved the issues earlier, but now again it has poped up not sure what the root cause of this issue..?
If you're only having issues calling the function in the same file, it's hard to help because you haven't shown HOW you're trying to call it. But I would suggest you try something like this:
// this is in abc.js
function qpValidations() {
this.addDaystoGetDate = function(noOfDays){
...
}
this.constructDate = function(){
this.addDaystoGetDate (2);// here issue is coming
}
}
const newQp = new qpValidations()
module.exports = newQp;
newQp.addDaystoGetDate();
addDaystoGetDate function required a parameter. try sending a parameter when you call the function.
newQp.addDaystoGetDate(5);
newQp.addDaystoGetDate("some text"); //or whatever you need
Finally got the answer, it was from one of my buddy:), the scope of this.addDaystoGetDate()
gets changed when it is called inside another this.constructDate() function. So as a solution assign "this" object to some variable like below, further can be referred same wherever we come across this
function validation(){
var refObj = this;
refObj.addDaystoGetDate =function(dayscount){
}
refObj.constructDate = function(){
refObj.addDaystoGetDate(2);
}
}
module.exports = new validtaion();

Durandal SPA issues with typescript

I am updated my durandal SPA application from VS_2012 to VS_2015 with TypeScript 1.8 which will generate JavaScript (ECMA5). I resolved all build errors.But I am unable to fix one typescript error called
"A 'return' statement can only be used within a function body"
I am working on view models. So I need return statement out side of function.
Due to build error I am not able to generate my java-script.
Below is my sample code in Type script:
class typescript1_8{
constructor(){
}
}
return new typescript1_8();
Java Script code needs to generate like below:
var typescript1_8 = (function () {
function typescript1_8() {
}
return typescript1_8;
}());
return new typescript1_8();
Note: I need return statement outside of class. It shouldn't throw any error in Type script as mentioned on above.
You cannot just return something from empty space, you can use Self-invoking function
(function() {
return new typescript1_8();
})();

nodeJS prevent access to code for variable passed into a function

I'm creating a plugin system using the following:
function Plugin(thingy, code)
{
var GLOBAL = null;
var arguments = null;
var process = null;
var require = null;
eval(code);
};
plugins.push(new Plugin(thingy, code));
Please don't get too excited about the eval(), using ('vm') or a sandbox is not an option as this will be a long running object until the user unloads it. It will also be running in it's own nodeJS instance so they can't affect other users. I'd still have the same problem passing in this object reference to a sandbox system anyway.
What I am concerned about is someone seeing the code of the thingy object that has functions they need to use e.g shoot()
console.log(thingy.shoot.toString());
A way around this was the following:
function thingy()
{
// They can't see this
var _shoot = function(someone)
{
// Load weapon
// Aim
// Fire
};
// They can see this
this.shoot = function(someone)
{
_shoot(someone);
};
};
This way if they console.log(thingy.shoot.toString()) they'll only see _shoot(someone); and not the actual code that handles the shooting process.
Please could someone help me with the following:
Is there an easier way to limit access to a passed in variables code?
I'm setting GLOBAL, arguments, process and require to null; are there others I need to worry about?

Javascript object member function referred to globally not recognized in callback

I'm having a problem with the following Javascript code (Phonegap in Eclipse):
function FileStore(onsuccess, onfail){
//chain of Phonegap File API handlers to get certain directories
function onGetSupportDirectorySuccess(dir){
//stuff
onsuccess();
}
function getDirectory(dir){
return "something" + dir;
}
}
var onFileStoreOpened = function(){
if (window.file_store instanceof FileStore){
console.log('window.file_store is a FileStore');
console.log(window.file_store.getDirectory('something'));
}
}
var onDeviceReady = function(){
window.file_store = new FileStore(onFileStoreOpened, onFileStoreFailure);
}
Here, I want to do some things to initialize file services for the app, and then use them in my initialization from the callback. I get the following error messages in LogCat:
07-03 06:26:54.942: D/CordovaLog(223): file:///android_asset/www/index.html: Line 40 : window.file_store is a FileStore
07-03 06:26:55.053: D/CordovaLog(223): file:///android_asset/www/cordova-1.8.1.js: Line 254 : Error in success callback: File7 = TypeError: Result of expression 'window.file_store.getDirectory' [undefined] is not a function.
After moving the code around and stripping out everything in getDirectory() to make sure it was valid, I'm not even sure I understand the error message, which suggested to me that getDirectory() is not seen as a member function of window.file_store, even though window.file_store is recognized as a FileStore object. That makes no sense to me, so I guess that interpretation is incorrect. Any enlightenment will be greatly appreciated.
I've since tried the following:
window.file_store = {
app_data_dir : null,
Init: function(onsuccess, onfail){
//chain of Phonegap File API handlers to get directories
function onGetSupportDirectorySuccess(dir){
window.file_store.app_data_dir = dir;
console.log("opened dir " + dir.name);
onsuccess();
}
},
GetDirectory : function(){
return window.file_store.app_data_dir; //simplified
}
}
var onFileStoreOpened = function(){
var docs = window.file_store.getDirectory();
console.log('APPDATA: ' + docs.fullPath);
}
var onDeviceReady = function() {
window.file_store.Init(onFileStoreOpened, onFileStoreFailure);
}
and I get
D/CordovaLog(224): file:///android_asset/www/base/device.js: Line 81 : opened dir AppData
D/CordovaLog(224): file:///android_asset/www/cordova-1.8.1.js: Line 254 : Error in success callback: File7 = TypeError: Result of expression 'docs' [null] is not an object.
All I want to do here is make sure certain directories exist (I've removed all but one) when I start, save the directory object for future use, and then retrieve and use it after all initialization is done, and I don't want everything in the global namespace. Of course I would like to be able to use specific instances when necessary, and I'm disturbed that I can't make it work that way since it demonstrates there is a problem with my understanding, but I can't even get this to work with a single, global one. Is this a Javascript problem or a Phonegap problem?
As it stands, your getDirectory function is a private function within FileStore. If you wanted to make it a 'member' or 'property' of FileStore, you would need to alter it a little within FileStore to make it like this:
this.getDirectory = function(dir){ };
or leave it how it is and then set a property....
this.getDirectory = getDirectory();
this way when new FileStore is called it will have getDirectory as a property because the 'this' keyword is always returned when calling a function with 'new'
Hope this quick answer helps. There's lots of stuff on the goog about constructor functions.
You understand it correctly. The getDirectory as it stands is a private function and cannot be called using the file_store instance.
Try this in the browser.
function FileStore(onsuccess, onfail){
function onGetSupportDirectorySuccess(dir){
//stuff
onsuccess();
}
this.getDirectory = function (dir){
return "something" + dir;
}
}
window.file_store = new FileStore('', ''); //the empty strings are just placeholders.
if (window.file_store instanceof FileStore){
console.log('window.file_store is a FileStore');
console.log(window.file_store.getDirectory('something'));
}
This will prove that the basic js code is working fine. If there still is a problem while using it in PhoneGap, comment.

Categories

Resources