Javascript reflection - generic toString - javascript

now when I put my own Object in alert function I see
[Object object]
that is pointless information. is there any way using reflection to get all fields and values of those fields?

JSON.stringify is often times builtin and can serialize most objects you pass to it.
That said, you should probably just use a debugger or console.log instead of alert-ing things.

Here is one of many. But better to use console.log() then alert
function objectToString(o){
var parse = function(_o){
var a = [], t;
for(var p in _o){
if(_o.hasOwnProperty(p)){
t = _o[p];
if(t && typeof t == "object"){
a[a.length]= p + ":{ " + arguments.callee(t).join(", ") + "}";
}
else {
if(typeof t == "string"){
a[a.length] = [ p+ ": \"" + t.toString() + "\"" ];
}
else{
a[a.length] = [ p+ ": " + t.toString()];
}
}
}
}
return a;
}
return "{" + parse(o).join(", ") + "}";
}

sure, maybe something like
function alertObject(0){
var str = "";
for(i in o)
str += i + " " + o[i] + "\n";
alert(str);
}
Edit :: Note this is just a silly little example.

Related

Looping over JavaScript object and adding string to end if not the last item

{
field_country: ["England", "Netherlands", "India", "Italy"],
field_continent: ["Europe"],
field_group: ["Building", "People", "Landscape"
}
I want to loop over each item and return the key and the array together with ending 'OR' for example:
field_country: "England" OR field_country: "Netherlands"
The last item should not end with 'OR' in the loop. I am not sure what the best process is for this using vanilla JS. So far my code is as follows:
Object.keys(facets).forEach(function(facetKey) {
if (facets[facetKey].length > 1) {
facetResults = facets[facetKey];
for (var i = 0; i < facetResults.length; i ++) {
if (i == 1) {
filter = "'" + facetKey + "'" + ":'" + facetResults[i] + " OR";
return filter;
} else {
filter = "'" + facetKey + "'" + ":'" + facetResults[i];
}
}
} else {
filter = "'" + facetKey + "'" + ": " + facets[facetKey] + "'";
return filter;
}
});
I would be very grateful for any assistance.
Thanks in advance.
You can do something like this with Object.entries and Array.reduce if you would like to get the final result in the form of an object:
const data = { field_country: ["England", "Netherlands", "India", "Italy"], field_continent: ["Europe"], field_group: ["Building", "People", "Landscape"] }
const result = Object.entries(data).reduce((r, [k, v]) => {
r[k] = v.join(' OR ')
return r
}, {})
console.log(result)
It is somewhat unclear what is the final format you need to result in but that should help you to get the idea. If ES6 is not an option you can convert this to:
const result = Object.entries(data).reduce(function(r, [k, v]) {
r[k] = v.join(' OR ')
return r
}, {})
So there are is no arrow function etc.
The idea is to get the arrays into the arrays of strings and use the Array.join to do the "replacement" for you via join(' OR ')
Here's the idea. In your code you are appending " or " at the end of your strings starting at index 0. I suggest you append it at the the beginning starting at index 1.
var somewords = ["ORANGE", "GREEN", "BLUE", "WHITE" ];
var retval = somewords[0];
for(var i = 1; i< somewords.length; i++)
{
retval += " or " + somewords[i];
}
console.log(retval);
//result is: ORANGE or GREEN or BLUE or WHITE
Your conditional expression if (i == 1) would only trigger on the second iteration of the loop since i will only equal 1 one time.
Try something like:
if (i < (facetResults.length - 1)) {
// only add OR if this isn't the last element of the array
filter = "'" + facetKey + "'" + ":'" + facetResults[i] + " OR";
return filter;
}
Here's your updated code:
Object.keys(facets).forEach(function(facetKey) {
if (facets[facetKey].length > 1) {
facetResults = facets[facetKey];
for (var i = 0; i < facetResults.length; i ++) {
if (i < (facetResults.length - 1)) {
filter = "'" + facetKey + "'" + ":'" + facetResults[i] + " OR";
return filter;
} else {
filter = "'" + facetKey + "'" + ":'" + facetResults[i];
}
}
} else {
filter = "'" + facetKey + "'" + ": " + facets[facetKey] + "'";
return filter;
}
});

Adding new line after bracket

I am proxying the function console.log to add some information to my logs and I am as well checking whether the information being logged is an object. I do this to avoid getting a log entry of the sort
2016-12-17 (22:12:51) > [object Object]
Code works fine when passing arguments that are not objects. For example, the command
console.log("hello","world");
prints
2016-12-17 (22:23:53) > hello
2016-12-17 (22:23:53) > world
But if I pass an object as well, the code will fail to insert a new line after the object. For example, the command
console.log("hello",{world:true,hello:{amount:1,text:"hello"}},"world");
prints
2016-12-17 (22:27:32) > hello
2016-12-17 (22:27:32) > { world: true, hello: { amount: 1, text: hello } } 2016-12-17 (22:27:33) > world
(note the missing line break after displaying the object).
Code
JQuery 3.1.1
main.js:
(function (proxied) {
function displayArg(argument){
var result= "";
if(typeof argument == "object") {
result += "{ ";
for (i in argument) {
result += i + ": ";
result += (displayArg(argument[i]));
result += ", "
}
result = result.substring(0,result.length - 2);
result += " }";
return result;
} else {
return argument;
}
}
console.log = function () {
var result = [];
for (i in arguments) {
var d = new Date();
result[i] = d.getFullYear() + "-" + (d.getMonth() + 1) + "-" + d.getDate() +
" (" + d.getHours() + ":" + d.getMinutes() + ":" + d.getSeconds() + ") > ";
result[i] += displayArg(arguments[i]);
result[i] += "\n";
}
return proxied.apply(this, result);
}
})(console.log);
I'm not fully understanding objective but what about something along the lines of the following oversimplified override:
var oldLog = console.log;
console.log= function(){
var d= new Date(),
dateString = // process string
.....
for(var i = 0; i<arguments.length; i++){
oldLog(dateString, arguments[i]);
}
}
TL;DR change the iterator variables so they don't share name, or add a "var" to the loop definition to make sure they don't escape your desired scope.
It turns out that the for loops from (my own) console.log and displayArg were "sharing" the value of the iterator i. This is because by not declaring the iterator variable, the scope was broader than what I needed. To clarify, look at this example:
console.log({isThis:"real life"},"hello","world")
The code from console.log will add a date to the beginning of result[0] and then call displayArg(arguments[0]), arguments[0] being {isThis:"real life"}. That function, will iterate over the objects properties, thus i will be assigned the value isThis. After the function returns, the value of i will not go back to 0. Instead, i will be isThis and as a consequence, the line
result[i] += "\n";
translates to
result[isThis] += "\n"
instead of
result[0] += "\n"
Probably the most sensible solution was to add a var in the for declaration of the iterators. The following code works as expected:
(function (proxied) {
function displayArg(argument){
var result= "";
if(typeof argument == "object") {
result += "{ ";
for (var i in argument) {
result += i + ": ";
result += (displayArg(argument[i]));
result += ", "
}
result = result.substring(0,result.length - 2);
result += " }";
return result;
} else {
return argument;
}
}
console.log = function () {
var result = [];
for (var i in arguments) {
var d = new Date();
result[i] = d.getFullYear() + "-" + (d.getMonth() + 1) + "-" + d.getDate() +
" (" + d.getHours() + ":" + d.getMinutes() + ":" + d.getSeconds() + ") > ";
result[i] += displayArg(arguments[i]);
result[i] += "\n";
}
return proxied.apply(this, result);
}
})(console.log);

javaScript funky cookie?

When I try to read my cookie that I have set something does not seem right
Here is my cookie functions
function readCookie(){
if (document.cookie !=""){
document.getElementsByName("eMail").innerHTML = alert("hello, " +
document.cookie.split("=")[1]);
}
}
//for setting cookies
function writeCookie(cName, cValue, expDate, cPath, cDomain, cSecure){
if(cName && cValue!= ""){
var cString = cName + " = " + escape(cValue);
if (expDate) cString += ";expires=" + expDate,toGMString();
if (cPath) cString += ";path=" + cPath;
if (cDomain) cString += ";domain=" + cDomain;
if (cSecure) cString += ";secure";
document.cookie = cString;
}
}
cookie being set
<input type="submit" value="Submit"
onclick="writeCookie('userId',document.getElementsByName('eMail').value)"/>
alert box
hello, undefined;__utma
thought on what this means?
The alert function returns undefined
So
document.getElementsByName("eMail").innerHTML = alert("hello, " +
document.cookie.split("=")[1]);
Is setting the html of eMail to undefined.
Also, getElementsByName returns a collection of elements.
Did you mean
document.getElementsByName("eMail")[0].innerHTML = "hello, " +
document.cookie.split("=")[1];
Or are there multiple elements with this name?
var eMailElements = document.getElementsByName("eMail");
for (var i = 0; i < eMailElements.length; i++)
eMailElements[i].innerHTML = "hello, " + document.cookie.split("=")[1];
Finally, if there's only one element you're targeting, you can give it a (unique) id, then simply do
document.getElementById("eMailId").innerHTML = "hello, " +
document.cookie.split("=")[1];
A few problems:
if(cName && cValue!= ""){
Change it to this:
if ((cName != "") && (cValue != "")) {
Also this line has a problem:
if (expDate) cString += ";expires=" + expDate,toGMString();
^ Should be a period
I see __utma in there which tells me one thing: You have Google ads somewhere on the page. They set cookies for tracking users, and your script is reading them. Your method of reading cookies is wrong anyway.
function readCookie(cName) {
var cookies = document.cookie.split(";"),
l = cookies.length, i, k, v;
for( i=0; i<l; i++) {
v = cookies[i].split("=");
k = v.shift();
v = v.join("=");
if( k == cName) return v;
}
}
Also, getElementsByName() returns a NodeList, so you need to get [0] off of it, or use getElementById() instead when writing the cookie - this is why the cookie result is undefined.

parsing JSON efficiently

so I'm parsing through a JSON object like so
if(val.function1!==""){
$("#contentFunction").text(val.function1);
}
if(val.function2!==""){
$("#contentFunction").text(val.function1 + "; " + val.function2);
}
if(val.function3!==""){
$("#contentFunction").text(val.function1 + "; " + val.function2
+ "; " + val.function3);
}
I'm wondiering if there is a better way of checking if my json object property is empty instead of having tons of conditions... this gets really messy if for instance I have up to val.function10
Thanks for your help
var strs = [];
for (var i = 0; i < 10; i++) {
var value = val["function" + i];
value && strs.push(value);
}
$("#contentFunction").text(strs.join("; "));
Something like this?
var content = "";
for (var prop in val) {
if (!val.hasOwnProperty(prop)) continue;
if (val[prop] !== "") {
content += "; " + val[prop];
}
}
Or in node.js (or modern browsers):
var c = Object.keys(val).filter(function (k) {
return val[k] !== "";
}).map(function (k) {
return val[k];
}).join("; ");
A tool like underscorejs will help you enumerate functions and properties.

convert JSON object to XML using javascript

I want to convert a JSON object to a XML String and I can't figure a proper way to do it.
I've found a neat little jQuery plugin called json2xml at https://gist.github.com/c4milo/3738875 but it doesn't escape the data.
How can I escape the data properly so that the browser's XML parser will work?
You can try this small library http://code.google.com/p/x2js/
There is no unique way of doing this. You should be using XML with a schema only, and JSON doesn't have such a schema. Any such transformation when done naively is likely to break.
Why don't you just use XML or JSON consequently?
You can use the external js available by google named x2js.js
You can see the demo over here.
jsFiddle Demo
you can use this function in your code to convert JSON to XML in js
var json2xml = function (o) {
var tab = "\t";
var toXml = function (v, name, ind) {
var xml = "";
if (v instanceof Array) {
for (var i = 0, n = v.length; i < n; i++)
xml += ind + toXml(v[i], name, ind + "\t") + "\n";
}
else if (typeof (v) == "object") {
var hasChild = false;
xml += ind + "<" + name;
for (var m in v) {
if (m.charAt(0) == "#")
xml += " " + m.substr(1) + "=\"" + v[m].toString() + "\"";
else
hasChild = true;
}
xml += hasChild ? ">" : "/>";
if (hasChild) {
for (var m in v) {
if (m == "#text")
xml += v[m];
else if (m == "#cdata")
xml += "<![CDATA[" + v[m] + "]]>";
else if (m.charAt(0) != "#")
xml += toXml(v[m], m, ind + "\t");
}
xml += (xml.charAt(xml.length - 1) == "\n" ? ind : "") + "</" + name + ">";
}
}
else {
xml += ind + "<" + name + ">" + v.toString() + "</" + name + ">";
}
}
return xml;
};
you get XML DOM in return, which in return you need to serialize
so in the main
var xmlDOM = json2xml(eval(jsonObj));
var oSerializer = new XMLSerializer();
var sXML = oSerializer.serializeToString(xmlDOM);

Categories

Resources