how to convert request.url to String - javascript

For the string, "http://localhost:9090/calculator?oper=add&n1=10&n2=20",
console.log(url.parse(req.url).query);
// gives `oper=add&n1=10&n2=20`
whereas
console.log(querystring.parse(req.url));
// gives { '/calculator?oper': 'add', n1: '10', n2: '20' }`
However, I'm not able to split it as these are objects, and not Strings. How do I convert them to strings?

Just use object.toString() to convert any variable into a string. Most scalar types and arrays will be converted. Other objects might need to have the method implemented, otherwise they will just return the text [Object] or something.
The second case it looks like console.log() used JSON.stringify(object), probably because the object doesn't have a method toString() implemented.

As you can see in what you provided, querystring.parse(req.url) mixed the url path with the key of the zero'th value. This means that querystring.parse should not be called on a full url, but only on the query part of the url. You can do that by using querystring.parse on the result of url.parse:
var parsedUrl = url.parse(testUrl); //would be url.parse(req.url)
var parsedQuery = querystring.parse(parsedUrl.query);
Now you can do parsedQuery.oper, parsedQuery.n1, parsedQuery.n2
Example
If for some reason you want to iterate the parsedQuery (for example if you don't know the keys are oper, n1, n2, ...), you can do it this way:
var parsedQueryKeys = Object.keys(parsedQuery);
parsedQueryKeys.forEach(function(key) {
console.log( key, parsedQuery[key] );
});
(There are multiple other solutions to iterate an object)
Finally, some libraries automate the parsing for you, so you can directly ask for the query values.
For example, with express's req.param:
console.log( req.param('oper'), req.param('n1'), req.param('n2') );
Find express on npm

Related

JSON.stringify(list) shows an array of strings, however, Array.isArray(list) is false

I am currently trying to debug the issue in the title.
Here's some additional information:
I am receiving the list from a DynamoDB set.
JSON.stringify(list) prints: ["elt1","elt2"]
Array.isArray(list) === false
list.map is undefined, list.forEach is undefined
const list2 = JSON.parse(JSON.stringify(list))
Array.isArray(list2) === true
I have tried the above hack, and it does solve the issue- but it is definitely not conventional.
You've made an erroneous assumption: just because something produces an Array when run through JSON.stringify() does not necessarily mean it in itself is an Array to start. Consider this example:
class MyClass {
toJSON() {
return ['a', 'b'];
}
}
const list = new MyClass();
console.log(JSON.stringify(list));
console.log(Array.isArray(list));
console.log(list.map);
console.log(list.forEach);
In other words - it's entirely possible for a class to override the toJSON() method and fundamentally alter how it is processed by JSON.stringify(). I would suspect what you're encountering is that list is not really an Array (as you allude) but rather some other type that behaves this way when being stringified.
It's return valid output (list.map is undefined, list.forEach is undefined),t because JSON.stringify() convert into a string and you can't apply any array function on in it.

JSON.stringify turned the value array into a string

I have a JS object
{
aString:[aNumber, aURL]
}
JSON.stringify() returns
{
"aString":"[number, \"aURL\"]"
}
I thought that valid JSON can have arrays as values. Can I have stringify return the JSON string without converting the array into a string? Basically I need turn the whole JS object straight into a string, without any modification.
Is there a better way to do this? I've been looking around but everyone suggests using JSON.stringify if I want an object to string, and no one has raised this problem.
EDIT: Thanks for the quick responses. Here is how I created my JS object, please let me know if I messed up and how!
cookie = {};
// productURL is a string, timer is a number, imageSrc is a URL string
cookie[productURL] = [timer, imageSrc];
// then, I just stringified cookie
newCookie = JSON.stringify(cookie);
If it is also relevant, I am setting an actual cookie's value as the resulting JSON string, in order to access it in another set of functions. Setting the cookie's value does do some URI encoding of its own, but I've actually been grabbing the value of newCookie in the Chrome console as well and it also returns the Array as a string.
If an object you're trying to stringify has a toJSON function, that will be called by JSON.stringify. Most likely you have an external library that's adding Array.prototype.toJSON.
For example, an old version (1.6) of Prototype JS will "conveniently" add that for you.
Prototype 1.6.1:
alert(JSON.stringify([1, 2, 3]));
<script src="https://cdnjs.cloudflare.com/ajax/libs/prototype/1.6.1/prototype.min.js"></script>
Whereas a newer version will not.
Prototype 1.7.2:
alert(JSON.stringify([1, 2, 3]));
<script src="https://cdnjs.cloudflare.com/ajax/libs/prototype/1.7.2/prototype.min.js"></script>
You could try deleting Array.prototype.toJSON just to see if that's what's causing the problem. If it is, you might want to look into upgrading/deprecating any libraries in your code that do weird things like that.
Prototype 1.6.1 (after deleting toJSON)
delete Array.prototype.toJSON;
alert(JSON.stringify([1, 2, 3]));
<script src="https://cdnjs.cloudflare.com/ajax/libs/prototype/1.6.1/prototype.min.js"></script>
Based on your description this is not what should happen.
If you have code like this:
var obj = {
aString:[123, "test"]
}
document.getElementById("out").value = JSON.stringify(obj);
it will generate the expected json:
{"aString":[123,"test"]}
also see https://jsfiddle.net/zudrrc13/
in order to produce your output the original object would have to look something like:
var obj = {
aString:"[123, \"test\"]"
}

generic filtering of JSON objects in js using Ramda

I like the implementation to be as generic and functional (as in functional programming) as possible, but generally speaking, i'm expecting a json objected with the following structure:
[
{
id: number,
prop1: string,
prop2: number,
prop3: string,
...,
propN: string
},
...
]
(basically, an array of object that contain N properties, some mapped to strings and others to numbers)
I am trying to implement a generic set of functions so that i'll be able to achieve something to this end:
var filteredResult = filter(by(property, value, lt\gt\eq\contains), collection);
basically, I'd like to return an array with the same object structure, filtered by a property string that I pass into by(), along with the value (either a string or a number) and the type of comparison i'd like to perform.
generally speaking, for numbers I'd like to be able to filter results where property values are greater/lessthan/in range of the value I pass, with with strings, or arrays of strings, I'd like to find out if the property value contains the value I pass into by().
Since I'm new to FP, i'm struggling with formatting my code to take advantage of the auto-currying Ramda provides and I'm having trouble composing the different functions while passing the arguments I want.
For example, I've written this function:
var byProperty = function(p) {return R.useWith(R.filter, R.propEq(p), R.identity)};
but when I try to use it like so:
var property = 'prop1', value = 15;
console.log( byProperty( property, value, collection ) );
I get a function instead of the filtered array.
I know I'm missing something trivial here, but it's been kind of hard for me to wrap my head around the way values and functions are passed around in Ramda.
but when I try to use it like console.log( byProperty( property, value, collection ) ) I get a function instead of the filtered array.
Yes, because your function takes only a single parameter, and returns a function. You could invoke it like this:
console.log( byProperty(property)(value, collection) );
but that's probably not what you want. Also, I think useWith is the wrong tool here, you just want a compose:
var byProperty = R.compose(R.filter, R.propEq);
though that still would need to be called like
console.log( byProperty(property, value)(collection) );
There is an open issue for this, but currying and composing variadic functions is not trivial. The best you'll get is probably
var byProperty = R.curryN(3, function(p, v, c) { return R.filter(R.propEq(p, v), c); });

How to create an object from a string containing initializer

I'm reading Object initializer strings from a database but can't see any easy way to turn them back into objects.
For example, given the following string, how would you turn it into an object?
var initializer = "{type: car, colour: red, engine: 2.0L}";
I ended up decoding them by just looping through piece by piece but felt that there must be a better way.
since your data isn't quoted there won't be a difference between datatypes everything must be parsed as string.
Instead of trying to parse this shit i would try to create valid parsable data in the first place.
In the unlikely case that, instead of returning JSON from the server as you should, you do end up parsing this yourself, here's how you might do that:
initializer
.replace(/^\{|\}$/g, '') // remove {} at beginning and end
.split(',') // break apart into key: val pairs
.reduce(function(result, keyval) { // build object
var parts = keyval.split(':').map(''.trim);
result[parts[0]] = parts[1];
return result;
}, {});
Of course, you'd probably want to add a bunch of bullet-proofing to that.
If you're using Underscore, you could use its ability to create an object from an array of [key, val] pairs:
_.object(initializer
.replace((/^\{|\}$/g, '')
.split(',')
.map(function(keyval) {
return keyval.split(':').map(''.trim);
})
);

array as function param

I have flash application, which creates array and calls javascript function.
var jsParams = ["3011","3012","3013","3014","3015"];
ExternalInterface.call("doCall", jsParams);
And this is my javascript function:
function doCall(params) {
console.log(params);
console.log(params[0]);
}
The output in the firebug is:
["3011","3012","3013","3014","3015"]
[
But for the second line i was expecting 3011 and not [. Then i have tried to call same function with same params from firebug and the function outputed:
doCall(["3011","3012","3013","3014","3015"]);
["3011","3012","3013","3014","3015"]
3011
My question is how to pass params from actionscript to javascript as array and not as string value.
Thanks.
It looks like the params variable is being passed in as a string, rather than an array.
Square bracket notation, when applied to a string, represents the character at the supplied index, which in this case would be the '[' (position 0).
You should look into JSON decoding to find a safe way to convert the string back into an array , I wouldn't recommend eval, and JSON.decode isn't widely supported.
have you tried encapsulating the array within another array?
ExternalInterface.call("doCall", [jsParams]);
I think a initial array is so you can pass mulitple sets of parameters

Categories