JSONP parsing in javascript/node.js - javascript

If I have an string containing a JSONP response, for example"jsonp([1,2,3])", and I want to retrieve the 3rd parameter 3, how could I write a function that do that for me? I want to avoid using eval. My code (below) works fine on the debug line, but return undefined for some reason.
function unwrap(jsonp) {
function unwrapper(param) {
console.log(param[2]); // This works!
return param[2];
}
var f = new Function("jsonp", jsonp);
return f(unwrapper);
}
var j = 'jsonp([1,2,3]);'
console.log(unwrap(j)); // Return undefined
More info: I'm running this in a node.js scraper, using request library.
Here's a jsfiddle https://jsfiddle.net/bortao/3nc967wd/

Just slice the string to remove the jsonp( and );, and then you can JSON.parse it:
function unwrap(jsonp) {
return JSON.parse(jsonp.slice(6, jsonp.length - 2));
}
var j = 'jsonp([1,2,3]);'
console.log(unwrap(j)); // returns the whole array
console.log(unwrap(j)[2]); // returns the third item in the array
Note that new Function is just as bad as eval.

Just a little changes and it'll work fine:
function unwrap(jsonp) {
var f = new Function("jsonp", `return ${jsonp}`);
console.log(f.toString())
return f(unwrapper);
}
function unwrapper(param) {
console.log(param[2]); // This works!
return param[2];
}
var j = 'jsonp([1,2,3]);'
console.log(unwrap(j)); // Return undefined
without return your anonymous function is like this :
function anonymous(jsonp) {
jsonp([1,2,3]);
}
because this function doesn't return so the output will be undefined.

Related

Using already created functions inside a new Javascript function

I'm beginner, so this question might be silly.
I had to do 4 Javascript Function, I will put them below
function Square(a) {
b=a*a;
return b;
}
//2.Functia Half//
function Half(a) {
b=a/2;
return b;
}
//3.Functia Percent//
function Percent(a,b) {
procent=a/b*100;
return procent + "%";
}
//4.Functia Area//
function Area(a) {
pi=3.14;
circlearea=a*a*pi;
final=circlearea.toFixed(0);
return final;
}
Now i have to create the last function, which does:
Applies Half function on the parameter I've given to the new function(a), stores is in a new variable(result), result becomes parameter for the function square, the result will be stored again in a new variable(resultSquare), resultSquare will be used in Area function and stored in a new variable(resultArea). In the end, I need percent function, to find out the percent of resultArea from resultSquare. I tried like this, but no luck:
function new function{
result=Half(a);
return result;
resultSquare=Square(result);
return resultSquare;
}
It just returns result variable and does nothing else. Can you help? Thank you in advance.
You can't return something twice. Once you return something, it breaks out of the function. Remove the first return result; statement and it should work.
Also why are you doing
function new function { }
The proper syntax is
function [Function Name](parameters) { }
The result exits the function - so anything after a return statement will not be run. You need to return the last item:
function newFunction(a) {
var result = Half(a);
var resultSquare = Square(a);
var resultArea = Area(a);
return Percent(resultSquare, resultArea);
}

How to dynamically change a function

I have a function that has already been assigned and I would like to append some additional script. When I display the function like:
var func = obj.when_clicked;
alert(func);
The following is displayed:
function object_123(){
object_123_Action();
}
The type is a "function" and the function is executed elsewhere which I cannot change, the code is:
this.when_clicked();
I need to modify the function by appending my own code so it becomes:
function object_123(){
object_123_Action();
my_clicked(obj);
}
Then add that back and over write the when_clicked function.
It does work if I manually add the code like:
obj.when_clicked = function object_123(){object_123_Action();my_clicked(obj);};
However, I do not know what is in the function initially, all I want is to append the:
my_clicked(obj);
I do need the obj to be the actual object of interest which is obj.
You can wrap it:
var f = this.when_clicked;
this.when_clicked = function() {
// Call the original
var rv = f.apply(this, arguments);
// your code here
// Return the original function's return value
return rv;
};
Function#apply calls the original with the specified this flag. arguments is provided by the JavaScript engine: It's a pseudo-array of the arguments your function was called with, so the above just passes all of them on.
Be sure to think about what it means if your function throws an exception, and catch them if you want to suppress them.
If you do this often, you can giev yourself a utility function:
function wrapFunction(f, wrapper) {
return function() {
var rv = f.apply(this, arguments);
wrapper.apply(this, arguments);
return rv;
};
}
Then
this.when_clicked = wrapFunction(this.when_clicked, function() {
// Your code here
});
Or if you want access to the original's return value, potentially changing it:
function wrapFunction(f, wrapper) {
return function() {
var rv = f.apply(this, arguments);
rv = wrapper.call(this, rv, arguments);
return rv;
};
}
Then
this.when_clicked = wrapFunction(this.when_clicked, function(rv, args) {
// Your code here, using `rv` and `args`, which is a pseudo-array
// Potentially update `rv`
return rv;
});
You can store your functions in an array on the object.
Then, loop though the functions in another function and execute them.
var myObj = { 'myfunctions': [ ] };
and to add functions:
myObj.myFunctions.push (function () { /*function code here*/ });
Or if you already have a named function:
myObj.myFunctions.push (nameOfFunction);
And to call all the functions, use this function (don't add this function to myObj)
function executeMyFunctions (myObj) {
for (var i = 0; i < myObj.myFunctions.length; i++) {
myObj.myFunctions[i]();
}
}
Used this answer on another question of #peter. Meant to post here.

How to create a "function that returns a function and splits csv file"? [duplicate]

This question already has answers here:
How do JavaScript closures work?
(86 answers)
Closed 8 years ago.
I'm learning JS and I need help with the following task:
I need to create a function compile_csv_search(text, key_name) that parses text in
the CSV format. (not required to handle quoting and escaping in values;
assume field values never contain commas or other special characters.)
A function must return a function that looks up a record by a value of the
field specified as the second argument to compile_csv_search. Assume that all
values in the key field are unique.
Sample usage:
var csv_by_name = compile_csv_search(
"ip,name,desc\n"+
"1.94.0.2,server1,Main Server\n"+
"1.53.8.1,server2,Backup Server\n",
"name");
console.log(csv_by_name("server2"));
console.log(csv_by_name("server9"));
...will print:
{ip: "10.52.5.1", name: "server2", desc: "Backup Server"}
undefined
** I didn't understand what does it mean "function that return function". How can function return another function?
Thank you!
P.S.
attaching my solution for your review
function compile_csv_search(csvServerData){
var header = csvServerData.split('\n')[0].split(",");
var spleatedServerData = csvServerData.split('\n');
return function(serverName)
{
for(var i = 1; i < spleatedServerData.length; i++){
var singleServer = spleatedServerData[i].split(',')
var result = {};
var exist = false;
for (var j = 0; j < header.length; j++) {
if(singleServer.indexOf(serverName) == -1)
break;
exist = true;
result[header[j]] = singleServer[j];
}
if(exist){
return(result);
break;
}
}
}
}
var csv_by_name = compile_csv_search(
"ip,name,desc\n"+
"10.49.1.4,server1,Main Server\n"+
"10.52.5.1,server2,Backup Server\n");
Functions in JavaScript are objects; they can be referred to by variables, passed as arguments and returned from functions like any other object.
Here's a function that returns an object:
function returnObject() {
var result = { a: 1, b: 2, c: 3 };
return result;
}
And here's a function that returns another function:
function returnFunction() {
var result = function() {
console.log('another function!');
}
return result;
}
Notice how they're really similar - object returned by the first function is a plain Object created using object literal syntax ({}), and the object returned by the second happens to be a function.
You could call the inner, returned function like this:
var out = returnFunction();
out();
Or even returnFunction()();
However, you can't just call result() - result is only defined inside of returnFunction. The only way to access it from outside is to retrieve it by calling the outer function.
Something like this would be fine:
function compile_csv_search(text, key_name) {
var lines = text.split('\n');
var keys = lines[0].split(',');
var key_index = keys.indexOf(key_name);
return function(value) {
for(var i = 1; i<lines.length; i++) {
current_line_values = lines[i].split(',');
if(current_line_values[key_index] === value) {
var result = {};
for(var j = 0; j<keys.length; j++) {
result[keys[j]] = current_line_values[j];
}
return result;
}
}
}
}
Also see this fiddle: http://jsfiddle.net/efha0drq/
You can always treat a function the same as any other js objects. Assign to a variable, pass to a function, store in an array... all are fine.
The magic in this example is that, you can read/write the variables defined in the compile_csv_search() function within the returned function. So it's possible to store something in the local variables of the defining function, and later retrieve from the returned one, even when the defining function has finished execution long time ago. You may have heard of "closure", right?

How to convert javascript array to function

I have an array of arbitrary values. I Wrote a function that transforms the array to an array of functions that return the original values, so instead of calling a[3], I will call a3.
Here is my code which does not work? code. It gives this error Cannot call method '1' of undefined.
var numToFun = [1, 2, { foo: "bar" }];
var numToFunLength = numToFun.length;
function transform(numTo) {
for (var i = 0; i < numToFunLength; i++) {
(function(num){
numTo.unshift(function() {
return num;
});
}(numTo.pop()))
}
}
var b = transform(numToFun);
console.log(numToFun);
console.log(b[1]());​
Others have already answered your question while I was writing mine but I will post it anyway - this may be somewhat easier to follow without all of those popping and unshifting:
function transform(numTo) {
var r = [];
for (var i = 0; i < numTo.length; i++) {
r[i] = (function (v) {
return function() {
return v;
}
}(numTo[i]));
}
return r;
}
(I have also changed the hard-coded length from numToFunLength to numTo.length so the transform() function would work for other inputs than only the global numToFun variable.)
See DEMO.
UPDATE: even more elegant way to do it using the Sugar library:
function transform(array) {
return array.map(function (v) {
return function() {
return v;
}
});
}
I like this syntax because it makes it more explicit that you want to map an array of values to an array of functions that return those values.
See DEMO.
Your function transform does not return anything. That is why b is undefined.
return numTo;
jsFiddle Demo
On the other hand, the array will be passed to the function as a reference anyways, so the original array will be changed. It is not a problem if you don't return anything, just omit the var b = transform(numToFun); line and simply write transform(numToFun).
Your transform function isn't returning anything. So b is undefined

javascript: Error passing back object

I get an error passing back an object from function to calling function.
What am I doing wrong?
function stStartProcessing()
{
var returnValue = {};
returnValue = srGetNextRecord(); // returnValue is undefined
}
function srGetNextRecord()
{
var returnValue = {};
returnValue.addressToArray = "AAA";
returnValue.sequence = "111";
console.log(returnValue); // this works
return returnValue;
}
There must be a different problem in your code, since what you posted works fine.
The modified code below shows 111. See this DEMO
function stStartProcessing()
{
var returnValue = {};
returnValue = srGetNextRecord(); // returnValue is undefined -- no, it's not
console.log(returnValue.sequence); //shows 111
}
function srGetNextRecord()
{
var returnValue = {};
returnValue.addressToArray = "AAA";
returnValue.sequence = "111";
console.log(returnValue); // this works
return returnValue;
}
stStartProcessing();
On a separate note, when writing JavaScript, please get into the habit of putting your opening braces on the same line—always. For what you have above it won't make a difference, but if you ever do this:
function foo()
{
return
{
x: 1,
y: 2
};
}
horrible things will happen—a semicolon will be inserted after the word return, thereby killing your return value, and causing a script error.

Categories

Resources