Object behaviour changed after assigned the variable - javascript

I have received a query/argument (matchQuery) from the client side through API.
When I console this request.query.matchQuery.on the server side it gives me {"count":{"$gt":1}} this is good for me.
when I assign this argument on the other variable like this
var aggregateQuery = {
$match: request.query.matchQuery
}
and now I console aggregateQuery its returns
{ '$match': '{"count":{"$gt":1}}' }
its behavior gets changed. But I don't want to single quotes on the right
side.
OUTPUT
{ '$match':{"count":{"$gt":1}}}
OR
{ $match:{"count":{"$gt":1}}}
OR
{ $match:{count:{$gt:1}}}

Best way to correct data that receive in serialized JSON is to parse it. JavaScript has JSON global object for facilitate JSON conversion and applied in application.
in your case evidence shows that request that came from client is like this:
"{\"count\":{\"$gt\":1}}"
but in your framework changed to STRING
typeof('{"count":{"$gt":1}}') ==> 'string'
that is not object
for use request.query.matchQuery as java script object your may convert it to JavaScript Object. for more details refer to below example:
var aggregateQuery = {
$match: JSON.parse(request.query.matchQuery)
}
Notice:
If you are not in STRICT MODE by adding
"use strict"
you can execute your code with
eval( code to be execute )
for examlpe
eval(`var e = { '$match':` + '{"count":{"$gt":1}}' + `}`)

Related

How to insert javascritpt function in Mongodb using Go driver or Golang

I saw the below code in mongodb official site, to insert a Javascript function in mongodb.
db.system.js.save(
{
_id: "echoFunction",
value : function(x) { return x; }
}
)
link is:
https://docs.mongodb.com/manual/tutorial/store-javascript-function-on-server/
I tried the procedures in mongoShell and it is working good.
Now, I want to store javascript function in to mongodb using golang.
I saw the below structure in gopkg.in/mgo.v2/bson package.
// JavaScript is a type that holds JavaScript code. If Scope is non-nil, it
// will be marshaled as a mapping from identifiers to values that may be
// used when evaluating the provided Code.
type JavaScript struct {
Code string
Scope interface{}
}
Does it relates to what I expected?
Please share your Knowledge.
Here is how First create a function that will return bson.JavaScript struct :
func mongoNow() bson.JavaScript {
return bson.JavaScript{
// place your function in here in string
Code: "(new Date()).ISODate('YYYY-MM-DD hh:mm:ss')"
}
}
And insert to your collections :
c := mongoSession.DB("YourDB").C("YourCollection")
err := c.Insert(
struct{LastSeen interface{}}
{
LastSeen: mongoNow()
}
)
Please do not forget to insert your appropriate import package.

define a long array in jquery click function

I have following long type session on server side code
long[] grouparray = ..;
Session["grouplist"] = grouparray;
Now I'm trying to get this session on View Page's jquery click function
$("#gpline").click(function () {
parseInt(#Session["grouplist"]);
var grouplistvalues = Session["grouplist"];
alert(grouplistvalues);
});
But this is having error once I debug using firebug
SyntaxError: expected expression, got ']'
parseInt(System.Int64[]);
You need to use Json.Encode and #Html.Raw on your c# data to make it compatible with your scripts.
Try this.
$("#gpline").click(function () {
var grouplistvalues = #Html.Raw(Json.Encode(Session["grouplist"])); // converting the session data into array of numbers in javascript variable
alert(JSON.stringify(grouplistvalues)); // stringify is used only to test.
});

How to parse returned css information using Selenium webdriver.executescript

Newbie to Javascript in Node environment...
Using this code below where the script is getting css values for a particular web element, how do I parse this in javascript?
driver.executeScript(script, ele).then(p => {
console.log(p);
})
The code above shows this result in the console.
{ class: 'container ng-scope', 'ng-controller': 'CalcCtrl' }
It's returned as type Object, so I can't figure out for example how to get the value of the key "class"...
If I change the code to this:
driver.executeScript(script, ele).then(p => {
console.log(p);
var obj = JSON.parse(p);
console.log(obj.class);
})
I get this error...
Where column 27 is the parse in JSON.parse...
The answer to this question, is this:
driver.executeScript(script, ele).then(p => {
if(p.class) console.log(p.class);
})
JavaScript returns undefined for any key in a JSON object that cannot be found, therefore, the If(p.class) ensures this item of data has a key named class and prints it out.

Store and retrieve Google Dart objects in JavaScript library containers

Store and retrieve Google Dart objects in JavaScript library containers
In a Dart application I am using an external JavaScript library to do various matrix calculations.
The specific functionality of the library is not important, what it's important is that I need to store and retrieve Dart object that I put in the matrix.
Dart Class - Lets image i have a dart object that which has a parameter called name
MyDartClass mydc = new MyDartClass(something, something);
mydc.name;
// Everything works as planned
Storing
matrix = js.context.matrix
matrix.cell(1,1).store("thing", new MyDartClass(something, something));
Retrieving
matrix.cell(1,1).has_object_of_type("thing");
// true
MyDartClass mydc = matrix.cell(1,1).retrieve("thing");
Do something with the object
mydc.name;
// Exception: The null object does not have a getter 'name'.
// NoSuchMethodError : method not found: 'name'
// Receiver: null
// Arguments: []
Does the library really work?
Yes it does. I have done the exact same thing in pure javascript many times and there are plenty of test to test the behaviour ( in Javascript )
Is Dart Broken?
When I try to use a javascriptified Hash to do the same behavoiur it works like a charm.
var options = js.map({ 'dart' : new MyDartclass(something, something));
var y = options["dart"];
js.context.console.log(y.name);
// Name is printed
What do you get out from the retrieve?
It seems that I get some kind of Dart Proxy
MyDartClass mydc = matrix.cell(1,1). retrieve("thing");
js.context.console.log(mydc);
DartProxy {id: "dart-ref-20", port: DartSendPortSync}
id: "dart-ref-20"
port: DartSendPortSync
__proto__: DartProxy
I belive that the lib stores the objects, deep down, in a hash map. But it seems like when I retrieve the object into the Dart I get something, but not in a way that I can work with it. So i need help since I don't know how to make it work.
Do I need to de-proxify the object?
Perhaps it IS a Dart bug when you try to retrieve objects from hashes inside objects
Perhaps I missunderstod everything that this is not suppose to work.
Passing and retrieving Dart objects inside the same scope is working. There's the following test case in the tests of js-interop to proove it :
test('retrieve same dart Object', () {
final date = new DateTime.now();
js.context.dartDate = date;
expect(js.context.dartDate, equals(date));
});
However there seems to be an issue with multiple scopes (and multiple event loops as well). There is no way to retain a dart object for now. So your dart object reference goes away at the end of scope. Here's a simple test case that fails :
test('retrieve same dart Object', () {
final date = new DateTime.now();
js.scoped(() {
js.context.dartDate = date;
});
js.scoped(() {
expect(js.context.dartDate, equals(date));
});
});
Please file an issue.

Avoiding eval when executing js returned from ajax call

I want to make an ajax call that will return a json object. One of this JSON object's properties will be the string of a function to be executed in the client. I realise this can easily be solved by using eval, but seeing the many disadvantages of eval, I'd rather avoid it. My question is:
Can I in some way return from the server some js code and execute it without resorting to eval?
As requested, here's some example code:
Server (Node.js):
var testFunc = function() {
alert('h1');
};
app.get('/testPack', function(req, res) {
var template = jade.render('h1 hi');
res.send({
template : template,
entity : testFunc.toString(),
data : {
id: "OMG I love this"
}
});
});
Client:
$(document).ready(function() {
$.ajax({
url: '/testPack',
success: function(data) {
$('body').append($(data.template))
alert(data.data.id);
var entity = eval(data.entity);
entity();
}
})
})
Of course, the returned function called entity wouldn't do such a silly thing, it would expose an API of the returned widget.
Just to clarify, I'd like to avoid having to make a separate call for the javascript itself. I'd rather bundle it with the template and data to render.
Easiest way to do that, is not to call a server through an ajax, but instead to create a new script tag on the page with the url pointing to a RESTful web-service that would output pure JavaScript (not JSON). That way your output will be evaluated by the browser directly without the use of eval.
To expand a little on my answer:
To get around the problems of running script in the global context you could do some tricks. For example, when you are adding script tag to the head, you can bind onload event (or rather fake onload event, since IE doesn't support onload on the script tag) to it, and if your response from the server will be always wrapped in the the function with a known name, you could apply that function from within your object. Example code below (this is just an example though):
function test ()
{
this.init = function ()
{
var script = document.createElement("script");
script.type = "text/javascript";
script.language = "javascript";
script.src = "test.js";
var me = this;
window.callMe = function () { me.scriptReady(me); };
var head = document.getElementsByTagName("head")[0];
head.appendChild(script);
};
this.scriptReady = function (object)
{
serverResponse.call(object);
};
this.name = "From inside the object";
this.init();
}
var t=new test();
The server response should look something like this:
function serverResponse()
{
alert(this.name);
}
window.callMe();
In this case, everything inside serverResponse() will use your object as "this". Now if you modify your server response in this way:
function serverResponse()
{
this.serverJSONString = { "testVar1": "1", "testVar2": 2 };
function Test()
{
alert("From the server");
}
Test();
}
window.callMe();
You can have multiple things being returned from the server and with just one response. If you don't like just setting variables, then create a function in your main object to handle JSON string that you can supply by calling this function from your response.
As you can see, it's all doable, it really doesn't look pretty, but then again, what you are trying to do is not pretty to begin with.
P.S. Just inserting a string inside tag will not work for IE, it will not allow you to do that. If you don't have to support IE, then you could get away with just inserting server response inside a newly created script tag and be done with it.
P.P.S. Please don't use this code as is, cause I didn't spend too much time writting it. It's ugly as hell, but was just ment as an example:-)
No, you can't do this by definition, because JavaScript functions are not valid JSON. See the spec here:
http://www.json.org/
If you're returning a string, then that's what it is: just a string. You can't evaluate it without eval. You can call whatever else you're returning whatever you want, but please don't call it JSON.
Here's an example of how I think this could work.
The json object represents what is returned from the server. The c and d properties contain function names as strings. If those functions are properties of some other object which exists in your page, then you should be able to call them using the object["property"] accessor.
See it working on jsFiddle: http://jsfiddle.net/WUY4n/1/
// This function is a child of the window object
window.winScopedFunction = function() {
alert("ROCK THE WIN");
}
// This function is a child of another object
var myObject = {
myFunction : function() {
alert("ROCK ON");
}
};
// pretend that this json object was the result of an ajax call.
var jsonResultFromServer= {
a : 1,
b : 2,
c : "myFunction",
d : "winScopedFunction"
};
// you can call the local functions like so
myObject[jsonResultFromServer.c]();
window[jsonResultFromServer.d]();
Yes, there's a way, but it has the exact same disadvantages as eval.
You can use the Function constructor to create a new function, and then call it. For example:
new Function(code)();
http://code.google.com/p/json-sans-eval/ is a fast JSON parser that does not use eval, and JSON.parse is becoming increasing widely available in new browsers. Both are excellent alternatives to eval for parsing JSON.
You can use the trick that Google does with Google Charts.
<html>
<head>
<script>
function onWorkDone(data) {
console.log(data);
}
</script>
<script src="callback.js"></script>
</head>
</html>
Then your callback.js is:
function doWork(callback) {
callback({result: 'foo'});
}
doWork(onWorkDone);
Basically, your script will call onWorkDone when the doWork completed. You can see a working example here:
http://jsfiddle.net/ea9Gc/
Do you have some example cases? Some things I can think of is you that you can just have a regular function inside your js file, and your server will return some parameters for your function to execute. You can even specify what function to use! (Isn't that amazing?)
// your js file
var some_namespace = {
some_function : function(a, b){
// stuff
}
}
// your server output
{
some_other_data: "123",
execute: {
func: "some_namespace.some_function",
params: [1, 2]
}
}
// your ajax callback
function(r){
window[r.execute.func].apply(this, r.execute.params);
}
The reasons of not using eval
Well, you already said it yourself. Don't use eval. But you have a wrong picture regarding why.
It is not that eval is evil. You are getting the reason wrong. Performance considerations aside, using eval this way allows a sloppy programmer to execute code passed from server on the client. Notice the "passed from server" part.
Why never execute code passed from server
Why don't you want to execute code passed from the server (incidentally that's what you're planning to do)?
When a browser executes a script on a web page, as long as the web site is valid -- i.e. really yours, and not a malware site pretending to be yours trying to trick your users -- you can be reasonably sure that every bit of code the browser is running is written by yourself.
Hacker's heaven -- script injection attacks
Now, if you are passing data from the server to your web application, and that data contains executable functions, you're asking for trouble. In the long, twisted journey of that data going from your server to your client's browser, it goes through the wild west called the Internet, perhaps through multiple layers of proxies and filters and converters, most of which you do not control.
Now, if a hacker is hiding somewhere in the middle, takes your data from the server, modify the code to those functions to something really bad, and sends it away to your client, then your client browser takes the data and executes the code. Voila! Bad things happen. The worse is: you (at the server side) will never know that your clients are hacked.
This is called a "script injection attack" and is a serious sercurity risk.
Therefore, the rule is: Never execute functions returned from a server.
Only pass data from server
If you only accept data from a server, the most that can happen whan a hacker tempers with it is that your client will see strange data coming back, and hopefully your scripts will filter them out or handle them as incorrect data. Your client's browser will not be running any arbitrary code written by the hacker with glee.
In your client-side script, of course you're sticking to the Golden Rule: Do not trust ANY data coming through the Internet. Therefore you'd already be type-check and validating the JSON data before using it, and disallowing anything that looks suspicious.
Don't do it -- pass functions from server and execute on client
So, to make a long story short: DON'T DO IT.
Think of another way to specify pluggable functionalities on the browser -- there are multiple methods.
I've had this same question, and I fixed it this way:
File: functions.js.php?f=1,3
$functions=array(
'showMessage' => 'function(msg){ alert(msg); }',
'confirmAction' => 'function(action){
return confirm("Are you sure you want to "+action+"?");
}',
'getName' => 'function getName(){
return prompt("What is your name?");
}'
);
$queried = explode($_REQUEST['f']);
echo 'var FuncUtils = {'; // begin javascript object
$counter=1;
foreach($functions as $name=>$function){
if(in_array($counter, $queried))
echo '"'.$name.'":,'.$function.',';
$counter++;
}
echo '"dummy":null };'; // end javascript object
File: data5.json
{
"action" : ['confirmAction','exit']
}
File: test.js
$(document).ready(function(){
$.getScript('functions.js.php?f=1,3');
});
function onBeforeExit(){
$.getJSON('data5.json', function(data) {
var func = data.action.shift();
FuncUtils[func].apply(null, data.action);
});
}

Categories