toString all the object datas - javascript

I have an object (json) like this in node.js:
var data = {
string : "name",
number : 123456789 ,
n : null ,
bool : false ,
bool2 : true
};
But I need to conver it to something like this:
{
string : "name",
number : "123456789" ,
n : "null" ,
bool : "false" ,
bool2 : "true"
};
I used this codes but not works.
for ( var index in data ){
data[index] = data[index].toString();
};
// or this
data.toString();
How can I fix it?
UPDATE
this data object is created as a new mongoose schema.

Your code looks fine, except for one thing: null doesn't have .toString() method. So, it's best to use String instead:
for ( var key in data ){
data[key] = String(data[key]);
};
String is a string constructor. It takes anything and produces a string representation of it.
Update
But this solution won't work for complex data structures. Though, if you need a JSON string, then you could use JSON.stringify with tricky replacer:
function replaceWithString(k, v) {
if ((typeof v === 'object') && (v !== null)) {
return v;
} else {
return String(v);
}
}
JSON.stringify(data, replaceWithString);
and if you want to make it pretty:
JSON.stringify(data, replaceWithString, 2);
N.B. As Bergi noticed in comments, you could use Object(v) === v instead of (typeof v === 'object') && (v !== null) to check that v is an object.
Update2
It looks like data in your example is a mongoose document.
The problem with mongoose is that it wraps all its object with the whole pack of nasty getters and setters to make them look like plain JS objects, which they are not.
So, if you're working with mongoose documents, you should call .toObject() or .toJSON() before trying to do anything with it:
data = doc.toObject(); // converts doc to plain JS object
Though, my second solution with JSON.stringify should work anyway, because stringify calls .toJSON() automatically.

for (var index in data) {
if (data[index] === null) {
data[index] = "null";
}
else if (data[index] === undefined) {
data[index] = "undefined";
}
else {
data[index] = data[index].toString();
}
}

Try this:
var val = null;
for(var key in data){
if(data.hasOwnProperty(key)){
val = data[key];
val = val === null ? 'null' : (val === undefined ? 'undefined' : val.toString());
data[key] = val;
}
}
It simply converts null to "null" and undefined to "undefined"
Note that values of your object must be a primitive data type for this to work. btw, this will work fine for your example.

A simple
JSON.stringify(data);
should work.
when doing
data[index].toString();
you are referencing a null on the third run. null has no such method toString().

Just thought I'd answer with a code that's a bit different:
for(var x in data){
data[x] = ""+data[x]+"";
}
Works.

Related

How to determine type of an expression inside string in Javascript?

I have one rest call that gives me information from query parameters and I need to determine whether they are a string or an int, array, boolean.
For example, if I have:
/.../something?id=1
I'll receive '1', but I know that's an integer.
Furthermore, I have:
/.../something?id=[1,2,3]
I'll receive '[1,2,3]' but I know it's an array. Finally, if I have:
/.../something?id=string
I'll receive 'string' and I should use it as a regular string.
Is regex the only way of doing that check for each type?
You can use JSON.parse with a catch block.
var options = ['12', '[1,2,3]', 'string', 'false', '{"x" : 2}', '/hey/', /hey/];
var parsed = options.map(x => {
try {
return JSON.parse(x)
} catch(e) {
return x;
}
});
var types = parsed.map(x => /\[object (.*)\]$/.exec(Object.prototype.toString.call(x))[1])
console.log(types);
Once you have a value
var value = "1"; //or whatever value after `id=`
you can apply this logic
var type = "";
var isNum = ( s ) => !isNaN(s);
var isObject = ( s ) => {
try { s = JSON.parse(s); return Array.isArray(s) ? "array" : "object" } catch( e ){ return false }
};
Now use them as
type = isNum( value ) ? "number" : ( isObject( s ) || "string" );
Note
If value is a function definition, it will still return a string
One way to solve this is to use trial-and-error methodologies:
If you have the value starting from [ and ending with ], you probably can assume that its an array. Use JSON.parse to be sure.
If first case doesn't match, use /^\d+$/ to test the string against integer values. Use parseInt() to be sure.
Lastly, if above both test cases fail, you can be sure that its a string, because strings can hold almost all type of values.
Savio,
One way you can handle it is to fetch the value and use switch/case statement with 'typeof' to see what they are.
Typeof explanation on MDN
// Numbers
typeof 37 === 'number';
typeof 3.14 === 'number';
// Strings
typeof 'bla' === 'string';
// Booleans
typeof true === 'boolean';
// use Array.isArray or Object.prototype.toString.call
// to differentiate regular objects from arrays
typeof [1, 2, 4] === 'object';

Add property to object when it's not null

I'm working on a small API and I want to update the data using HTTP PATCH REQUEST without using a bunch of if statements. I'm trying to fill the outgoing data object with the changed data only.
update() {
let prop1 = hasBeenChanged.prop1 ? changedData.prop1 : null;
// ...
let propN = hasBeenChanged.propN ? changedData.propN : null;
let data: ISomething = {
// something like --> property != null ? property: property.value : nothing
}
}
Is there any way to create the data object dynamically?
You could use Object.assign in combination with the ternary operator:
let data = Object.assign({},
first === null ? null : {first},
...
);
This works because Object.assign will skip over null parameters.
If you are sure that the property value is not going to be "falsy", then it would be bit shorter to write:
let data = Object.assign({},
first && {first},
...
);
Assuming the object is going to be stringified at some point, since stringification ignores undefined values, you could also try
let data = {
first: first === null ? undefined : first,
...
}
Depending on the JS version you are using, you can use the spread operator ...
const getData = data => ({
...data.first && { 'Custom First Prop Name': data.first },
...data.second && { 'Custom Second Prop Name': data.second },
...data.third && { third: data.third },
...data.fourth && { fourth: data.fourth },
});
Non-inline solution
If you don't need to add the value inline, it is pretty straightforward and clean to write your assignment like this.
const val1 = 1
const val2
const data = {}
val1 && (data.a = val1) // 1
val2 && (data.b = val2) // Not added
// data = { a : 1 }
NOTE: This will not work if the value is falsey

Extracting data from JSON.stringify

The data I receive back from my JSON.stringify looks like this.
{"action":"deleted","data":{"latitude":9,"longititude":8,"_type":"locationcurrent","id":49,"user":"7"}}
But I can not seem to get the data inside of the objects. Mainly I want the value for action, "deleted", and the values for my data, like id:"49". But im having problems using this equation to try and get the data out.
function replacer(key, value) {
if (typeof value === "string") {
return value;
}
return undefined;
}
var jsonString = JSON.stringify(message, replacer);
console.log(jsonString);
All I get back from this is,
data:{}
Your problem is that the first value that is passed to the replacer is the object itself. You replace this object by undefined because it is not of the type string.
You need it change it that way:
function replacer(key, value) {
if ( key === '' || typeof value === "string") {
return value;
}
return undefined;
}
But as Phatjam98 said, it does not make much sense to filter out one value that way.

Swap undefined value with empty string

I have a parse method in a backbone app that builds a JSON object out of an array, however if a value is empty, it is written as undefined, which breaks the behavior of other methods, I need to set undefined values as empty strings and am having trouble doing that, any help is greatly appreciated.
Note: in this case I am trying to set the value of value: to an empty string if obj[key] = undefined
code:
parse: function(data){
return data.map(function(obj){
var key = Object.keys(obj)[0];
return {
attribute: key,
value: obj[key]
};
});
}
toQueryString: function(){
var obj = this.toQueryData(),
qs = [];
for (key in obj) {
qs.push(key + "=" + obj[key]);
}
return qs.join('&')
},
toQueryData: function(){
return this.reduce(function(memo, model){
memo[model.get('attribute')] = model.get('value');
return memo
}, {});
}
Use a ternary condition:
value: obj[key] ? obj[key] : ""
Or (as pointed out by #Derek朕會功夫),
value: obj[key] || ""
You need to check if the object has the property - key.
value: obj.hasOwnProperty(key) && obj[key] != undefined ? obj[key] : ""
// or you could write it like this (which I prefer, think the bracket syntax is a little bit uglier):
value: obj.hasOwnProperty(key) && obj.key != undefined ? obj.key : ""
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty
Since your using backbone you could use underscores defaults method:
return _.defaults({attribute: key, value: obj[key]}, {value: ''});
toQueryString: function(){
var obj = this.toQueryData(),
qs = [];
for (key in obj) {
qs.push(key + "=" + (obj.hasOwnProperty(key) && obj.key != undefined ? obj.key : ""));
}
return qs.join('&')
}
This ended up being the solution, thanks Marko!

Determining if a Javascript object is a "complex" object or just a string

I want to be able to pass either a string literal,
'this is a string'
or a javascript object,
{one: 'this', two: 'is', three: 'a', four: 'string' }
as argument to a function, and take different actions depending on whether it's a string or an object. How do I determine which is true?
To be specific, I want to iterate over the properties of an object, and do some parsing if a property is a string, but nest recursively if the property is an object. I've figured out how to use $.each() to iterate over the properties of the object, but if I just do this with the string, it treates the string as an array of letters rather than as a single thing. Can I get around this some other way?
var data = {
foo: "I'm a string literal",
bar: {
content: "I'm within an object"
}
};
jQuery
$.each(data, function(i, element){
if($.isPlainObject(element){
// we got an object here
}
});
There are similar methods like $.isArray() or $.isFunction() within the jQuery lib.
Native Javascript
for(var element in data){
if(toString.call(element) === '[object Object]'){
// we got an object here
}
}
To use the hack'ish way with toString has the advantage, that you can identify whether it is really an object and an array. Both, objects and arrays would return object by using typeof element.
Long story short, you cannot rely on the typeof operator to distinguish true objects and arrays. For that you need the toString.call(). If you just need to know whether it is any object or not, typeof is just fine.
var a = 'this is a string';
console.log(typeof a); // Displays: "string"
var b = {one: 'this', two: 'is', three: 'a', four: 'string' };
console.log(typeof b); // Displays: "object"
Therefore:
if (typeof yourArgument === 'string') {
// Do the string parsing
}
else if (typeof yourArgument === 'object') {
// Do the property enumeration
}
else {
// Throw exception
}
UPDATE:
Some further considerations:
See #Andy E's comment below.
typeof null returns "object" as well. The same applies to any other object, including arrays.
Try this:
function some_function(argument) {
if (typeof(argument) == "string" || argument.constructor == String) {
// it's a string literal
} else if (argument && typeof(argument) == "object" && argument.constructor != Array) {
// it's an object and not null
} else {
// error
}
}
Thanks to Andy E for the tipp with argument.constructor.
Try the typeof operator. It will return object for objects and string for strings.
you can do something like this
function something(variableX){
if (typeof(variableX) === 'object'){
// Do something
}else if (typeof(variableX) === 'string'){
// Do something
}
}
I was having a similar problem and I think I figured out a solution. Here is my sample code for anyone who is interested.
var propToDotSyntax = function (obj) {
var parse = function (o, n) {
var a = [], t;
for (var p in o) {
if (o.hasOwnProperty(p)) {
t = o[p];
if (n !== undefined) tmp = n + '.' + p;
else tmp = p;
if (t && typeof(t) === 'object') a.push(arguments.callee(t, tmp));
else a.push(tmp + '=' + t);
}
}
return a;
};
return parse(obj).toString();
}
var i = { prop: 'string', obj: { subprop: 'substring', subobj: { subsubprop: 'subsubstring' } } };
propToDotSyntax(i);
This will go through all the properties of an object — even if the properties are objects themselves — and return a string with the following values in dot syntax.
"prop=string,obj.subprop=substring,obj.subobj.subsubprop=subsubstring"
I got the inspiration from DavidPirek.com — Thanks Mr. Pirek!

Categories

Resources