How to get input from Chrome's Javascript console? - javascript

Is there a way to programmatically get input from the Javascript Console of Google Chrome, similar to readline() in Firefox?

A tricky way to do this is assigning a getter to a property of a window object
Object.defineProperty(window, 'customCommand', {
get: function() {
console.log("hey");
return "hey";
}
});
So when you type "customCommand" (without parenthesis) it will print your console.log text to the console while the console is "getting" the variable.
You will still have to return something though, and I'm not sure how you could change the order so that the value is returned first and the text in the console appears second. It's definitely possible though, I've seen this happen.

This is an indirect method of taking inputs:
Declare a function in JavaScript:
function your_command_here() {
//code
}
As Chrome's console basically provides methods for communicating with the page's contents, like JavaScript variables, functions, etc., so declaring a function as a receivable command can be an option.
In the console, for providing input, the user shall type:
your_command_here()
Another workaround is:
Declare a function:
function command(var cmnd) {
switch(cmnd) {
case "command1":
//code
break;
}
}
So the user can (more conveniently) type:
command("user's command here")

We can do is hook the console.log so whenever it logs something we can access, otherwise there is no such direct method as like in firefox which does this possible for us in a simple single line code.
var tempStore = [];
var oldLog = console.log;
console.log = function() {
tempStore.push(arguments);
oldLog.apply(console, arguments);
}

You might need to incorporate jsh (Javascript Shell) in your environment if you are working with console IO. See http://code.google.com/p/jsh/ for the how-to. Hope this helps.

Sorry, doesn't work on Chrome JS Console, just works on the repl from repl.it
Example from repl.it:
console.log("Enter your name:");
console.read(function(name) {
console.log('Your name is ' + name + '.');
});

Here is a solution to input from the console.
Try this out!!
process.stdin.resume();
process.stdin.setEncoding('ascii');
var stdInput = "";
var stdInputArr = "";
var index = 0;
process.stdin.on('data', function (data) {
stdInput += data;
});
process.stdin.on('end', function () {
stdInputArr = stdInput.split("\n");
main();
});
// Reads complete line from STDIN
function readLine() {
return stdInputArr[index++];
}
//call this function in the main function
javascript node.js jquery consoleweb

The better you can do is use:
myVar = prompt('Which value do your want?')

Related

Is there a way to get data from user using browser's console

I would like to capture user's input through browser's console.
Currently I get input using JS's prompt, like so:
var a = prompt("Enter your numbers").split(",");
console.log(a);
But I would like data to be entered through the console.
Is there a way to do this with Javascript or Typescript?
EDIT
John Weisz gave good answer, this would normally work, it won't work with my problem.
You see, the user will use the console to enter a string of numbers which I will store into an array and check for duplicates...
Then print those duplicates with an object to the console...
var a;
window.cliApi = {
setValue: function (value) {
a = value;
}
}
var counts = {};
a.forEach(function(x){
counts[x] = (counts[x] || 0) +1; });
console.log(counts);
Sort of. You can create a globally exposed API that the user can use from the console, for example:
var a;
window.cliApi = {
setValue: function (value) {
a = value;
},
getValue: function () {
return a;
}
}
Then, in the browser console, you can type:
cliApi.setValue("hello world")
After which your variable will be populated.
Fiddle here.
Note, that with JSFiddle, you will need to set the console scope to the result frame instead of top (you do this inside your dev tools), as your code is running inside a frame. This is not required if you host your code yourself (and not from a frame).

Best way to detect when a function is called from the console

I would like to know the best way to detect when a method or function is directly called through the console. As far as I currently understand, it's not possible to directly detect it on identical function calls, but using the .call() and .apply() methods of a function I can pass additional data through the this object.
Given the following code structure:
(function(){
var Player = {money: 0};
window.giveMoney = function(amount){
if (this.legit !== true)
throw new Error("Don't try to cheat!");
Player.money += amount;
}
})();
I could call the function using
window.giveMoney.call({legit: true}, 300);
in my actual code to tell a direct call from the console and my own code apart, but this is obviously not fool-proof, since the same code can also be executed from the console to achieve the desired effect.
I would want a way to be able to call the function from both places and then tell the locations of the call apart. If there's no way to do that, what's the best way to try and prevent the execution anyway? Is it best to just not expose any methods at all, and keep everything inside a single closed-off anonymous function?
To prevent global access make sure your code is in a closure. If you want to expose an API you can do so using the module pattern.
Closure
(function() {
var Game = {};
Game.giveMoney = function(money) {
console.log('Gave money (' + money + ')');
};
})();
Wrap all your private code in an IIFE (Immediately Invoked Function Expression) which will lock it up into a closure.
Module
Then expose only custom functions back out of the closure so you can use them on the console (with supervision of course).
window.Game = (function() {
var player = {
money: 500;
};
player.giveMoney = function(money) {
console.log('Gave money (' + money + ')');
player.money += money;
};
player.takeMoney = function(money) {
console.log('Took money (' + money + ')');
player.money -= money;
};
return {
giveMoney: function(money) {
console.error('Don\'t Cheat! A fine was charged.');
player.takeMoney(Math.floor(player.money / 0.05));
}
};
})();
window.Game.giveMoney(200);
You can spool all function calls through a central access point with a boolean variable, that can serve as a indicator whether the call is from a console or not....
var maths = {
add: function(p1,p2)
{
console.log(p1,p2);
}
}
var invoker = {
invoke: function(fu,isconsole)
{
if(isconsole)
{
console.log("Called from console");
}
//invokes the function with all parameters intact
fu;
}
}
//Call without console
invoker.invoke(maths.add(2,3));
//Call with console
invoker.invoke(maths.add(2,3),true);
Hope it helps!!!
You can use the monitor() command in the console to monitor when a function is called. https://developer.chrome.com/devtools/docs/commandline-api#monitorfunction
Just run monitor(functionName); and whenever the function is called it will output a message in the console.

Javascript: uncaught typeerror undefined is not a function for object methods

I make a simple quiz game. Here is some relevan methods that i have inside one object.
But doesn't work. I always get an error within 'rightAnswerGot' function. Console drops
"uncaught typeerror undefined is not a function for object methods" for this.addVariantsHtml(this.updateCharacter());
BasicGame.Game.prototype = {
actionOnClick: function (button) {
var log;
if(button.value==this.char_bubble.text) {
setTimeout(this.rightAnswerGot,1000);
} else {
// wrong
swoshsound.play();
}
console.log(log);
},
rightAnswerGot: function (){
this.addVariantsHtml(this.updateCharacter());
},
addVariantsHtml: function(id) {
this.answer = this.getAnswersVariants(id);
for (var i = 0; i < 6; i++) {
this.button[i].value = this.answer[i]['trans'];
this.button[i].char_id = this.answer[i]['id'];
this.ans_text[i].setText(this.answer[i]['trans']);
}
},
updateCharacter: function() {
var i = this.getRandomCharacter();
console.log("updateCharacter: "+i + " " +this.chars[i]);
this.char_bubble.setText(this.chars[i].getPath());
return i;
}
}
The aim is to froze the game for a second, when user choose the right answer, and than go to next question. Any ideas why does it happens?
Thanks
Looks like a classic JavaScript scope issue to me. However as you've tagged this question as using Phaser, I would suggest you use a Phaser Timer event to avoid scope problems. Specifically:
setTimeout(this.rightAnswerGot,1000);
replace it with:
this.game.time.events.add(Phaser.Timer.SECOND, this.rightAnswerGot, this);
Which will create a single 1 second timer that fires only once, calling your function at the end of it. You can use 1000 instead of Phaser.Timer.SECOND of course.
I would image that whats happening is that its trying to call the this.addVariantsHtml method, before its calling this.updateCharacter and getting the ID.
So your probably expecting that when it runs, for it to be something like:
this.addVariantsHtml(1);
But its actually trying to run
this.addVariantsHtml(this.updateCharacter());
So just do this:
var id = this.updateCharacter();
this.addVariantsHtml(id);
Either that or you need to look into method chaining/piping, which is just complicated and doesnt need to be used for this situation, but is interesting :)
Ok I found something that made it work!!
Here is a solution:
actionOnClick: function (button) {
var log;
if(button.value==this.char_bubble.text) {
var context=this;
setTimeout(function() {
context.addVariantsHtml(context.updateCharacter());
},1000);
} else {
// wrong
swoshsound.play();
}
console.log(log);
},

DevTools Console - Turn it off

I'm currently building a library in Javascript and really like Google's DevTools for debugging it. Unfortunately I don't want my library to log when I release.
This is how my logger is currently setup.
var debug = false;
var increaseSomething = function()
{
// Random Code...
if (debug) { console.log("Increased!"); }
}
Unfortunately this is quite annoying, I shouldn't have to check if debug is on before logging to the console every call.
I could try to encapsulate the console in my own logging object but I feel that wouldn't be such a great idea. Any thoughts?
You could do this?
if (!debug) {
console.log = function() {/* No-op */}
}
As you mentioned, you might not want to kill all logging for everyone. This is how I usually go about it. Define these in some utility file, as global functions. I usually add additional functions for LOG, WARN, ERROR and TRACE, and log these based on a verbosity level.
// Define some verbosity levels, and the current setting.
_verbosityLevels = ["TRACE", "LOG", "WARN", "ERROR"];
_verbosityCurrent = _verbosityLevels.indexOf("LOG");
// Helper function.
var checkVerbosity = function(level) {
return _verbosityLevels.indexOf(level) <= _verbosityCurrent;
}
// Internal log function.
var _log = function(msg, level) {
if(!debug && checkVerbosity(level)) console.log(msg);
}
// Default no-op logging functions.
LOG = function() {/* no-op */}
WARN = function() {/* no-op */}
// Override if console exists.
if (console && console.log) {
LOG = function(msg) {
_log(msg, "LOG");
}
WARN = function(msg) {
_log(msg, "WARN");
}
}
This also allows you to add important information to your log, such as time, and caller locations.
console.log(time + ", " + arguments.callee.caller.name + "(), " + msg);
This may output something like this:
"10:24:10.123, Foo(), An error occurred in the function Foo()"
I thought about encapsulating the console logger again and instead of coming up with an entire object to encapsulate the console I created a function that takes in a console method. Then it checks if debugging is on and calls the function.
var debug = true;
var log = function (logFunction) {
if (debug) {
logFunction.apply(console, Array.prototype.slice.call(arguments, 1));
}
};
var check = function (canvas) {
log(console.groupCollapsed, "Initializing WebGL for Canvas: %O", canvas);
log(console.log, "cool");
log(console.groupEnd);
};
check(document.getElementById('thing'));
I do like #Aesthete's ideas but I'm not yet wanting to make the encapsulated console.
Here is the jsfiddle as example: http://jsfiddle.net/WRe29/
Here I add a debugCall to the Objects prototype. Same as the log function just a different name so theirs no 'overlap' Now any object can call debugCall and check its debug flag.
Object.prototype.debugCall = function(logFunction)
{
if (this.debug) { logFunction.apply(console, Array.prototype.slice.call(arguments, 1)); }
};
var Thing = { debug : true /*, other properties*/ };
Thing.debugCall(console.log, "hello world");
EDIT:
My initial thoughts were to use an object as the 'configuration' to indicate whether the object should be logging. I've used this a while and liked the configuration concept but didn't think everyone would be so keen to use configuration objects in their code alongside a function being passed to a extended function on object. Thus I took the concept and instead looked at function decoration.
Function.prototype.if = function (exp) {
var exFn = this;
return function () {
if (exp) exFn.apply(this, arguments);
};
};
var debug = false;
console.log = console.log.if(debug);
console.group = console.group.if(debug);
// Console functions...
myFunction = myFunction.if(debug);
It's very simple almost unnecessary to even have a decoration function that checks an expression but I am not willing to put if statements everywhere in my code. Hope this helps someone out maybe even spark their interest with function decoration.
Note: This way will also kill logging for everyone unless you setup the if extension correctly ;) *cough some type of object/library configuration indicating debug
https://github.com/pimterry/loglevel
Log level Library::Try whether this suits ur need.

javascript function parameter place

How to write function(object) with 2 methods (alert and console.log) to be able to use it like this:
fname("text").alert //-now text is alerted;
fname("text").cons //-now text shows in console log.
the methods are not important byt the way of execution. I know that it must be self invoiking function but i cant do it. I dont want to use it this way - fname.alert("text").
Greetings
Kriss
It's not possible in any sane way that works everywhere. The example you posted would require you to define an accessor for those properties - and that only works with modern JS engines.
Anyway, here's code that would actually do this. But please do not use this in any real application! See the last code block for a better solution
function fname(message) {
var obj = {};
Object.defineProperty(obj, 'alert', {
get: function() {
alert(message);
}
});
Object.defineProperty(obj, 'cons', {
get: function() {
console.log(message);
}
});
return obj;
}
This works because fname('hello').alert will cause the getter function for the alert property to be executed - and while such a function should usually return a value there's nothing to stop it from doing something like showing an alert() message.
What you could achieve in a way that works everywhere would be something like that though:
fname('text').alert();
fname('text').cons();
This could be done like this:
function fname(message) {
return {
alert: function() {
alert(message);
},
cons: function() {
console.log(message);
}
}
}
function fname(str) {
return {
alert:function(){alert(str)},
cons:function(){console.log(str)}
}
}
Doing fname("text").alert() alerts text.

Categories

Resources