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.
Related
Hey guys I have a tough one here
I need to store and retrieve an object with nested elements and a function which returns serialized in the clients localStorage. As for the storing and retrieving, it works. But I am having an issue with functions which have been stringyfied, but won't go back to be actual functions anymore.
Here is an example of an array element:
As far as I am aware, this is called serialized in the JSON-Jargon. And the goal would be to unserialize them again in order to make them function again. In order to be able to store functions in the JSON format, I had "replace and revive" the arrays which had to be stored.
let replacer = (key, value) => {
if (typeof value === "function") {
return value.toString();
}
return value;
I turn functions to string and return them to the JSON. I invoke this helper function like this:
localStorage.setItem(
"currentConfiguration",
JSON.stringify(
tableRef.current.dataManager.columns,
replacer,
2
)
Here is the code which is actually supposed to do: Undo what the replacer did and return actual functions instead of their strings.
let reviver = (key, value) => {
if (typeof value === "string" && value.indexOf("function ") === 0) {
let functionTemplate = `(${value})`;
return eval((functionTemplate));
}
return value;
};
Currently I am facing this screen whenever I try to render:
Would appriciate if anyone could lend a helping hand
I am able to convert cyclic Object to JSON. Now, i want to convert JSON to cyclic Object
//Cyclic to JSON conversion which works fine
<script>
var seatObj;
seen = [];
var replacer = function(key, value) {
if (value != null && typeof value == "object") {
if (seen.indexOf(value) >= 0) {
return;
}
seen.push(value);
}
return value;
};
seatObj = JSON.stringify(obj.part.data, replacer);
</script>
If you want to restore your cyclic information, you need to retain it somehow. Traditionally you would generate or keep track of existing object ids to retain the information in your json output.
I am using second parameter of JSON.parse() to modify the result, but I don't quite clear about the order of the function parameter and also how it work
I have read the document about the using of the reviver function (e.g https://www.ecma-international.org/ecma-262/6.0/#sec-json.parse and https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse).
From what I understand, this function would work with object, and first parameter is key or property name, second function is value or property value. What I don't understand is the return value of the function.
This is what it is done in example
var obj1 = '{"a":1, "b":42}';
let text = JSON.parse(obj1, (key, value) => {
if (typeof value === 'number'){
return value * 2
}
else{
return value
}
}
)
console.log(text) // {"a": 2, "b": 84}
This work well. But when I try to modify the code since I know all value is number already
var obj1 = '{"a":1, "b":42}';
let text = JSON.parse(obj1, (key, value) =>{
return value * 2
})
console.log(text) // NaN
It is strange to me why when I delete the return value it doesn't work. I mean, with the function none of the value return undefined when I value*2 it. I then try another test
var obj1 = '{"a":1, "b":42}';
let text = JSON.parse(obj1, (key, value) => {
if (typeof value === 'number'){
console.log('This is in if',key, value)
return value * 2
}
else{
console.log('This is in else', key, value)
return value
}
}
)
console.log(text)
Another strange thing happen when the code in else statement run even when it suppose not to run because the condition is incorrect. And when it run it even print out the obj1 object, which I didn't include in the statement.
Because it will also iterate thorough the object which is {"a":1, "b":42}.It will start from most nested level and then will go the original value itself which is {"a":1, "b":42}.
According to MDN
If a reviver is specified, the value computed by parsing is transformed before being returned. Specifically, the computed value and all its properties (beginning with the most nested properties and proceeding to the original value itself) are individually run through the reviver
By the way you can shorten your function.
var obj1 = '{"a":1, "b":42}';
let text = JSON.parse(obj1, (_, value) => value * 2 || value)
console.log(text)
I'm working on a way that takes advantage of the replacer function argument in JSON.Stringify in JavaScript in order to change the word-case (toUpper /toLower case), the problem is my JSON is not straight key:value, some values are keys also and they have values themselves, so I need to go through all keys and values, check if the value is also a key and make sure I change the case (toUpper or toLower) for all keys and values.
I know that the replacer function in JSON.Stringify(object,ReplacerFunction) iterates through all keys and values and makes the modifications inside then return keys and values, but although I've been reading about this for a wWhile I can't apply it, and I am not sure if I should apply recursion inside the replacer function or how, any help is appreciated.
Code I had:
function _replacer(name,val){
if(typeof val != "object"){
return val.toString().toUpperCase()
}
if(typeof name != "object"){
return name.toString().toUpperCase()
}
console.log("key = "+name+" type: "+typeof name);
console.log("value ="+val+" type: "+typeof val);
}
Also:
function _replacer(name,val){
if(typeof val != "object" &&typeof val ==="string"){
return val=val.toUpperCase()
}
if(typeof name != "object" &&typeof name ==="string"){
name=name.toUpperCase()
}
return val;
}
Also , i eventually got to this stage :
var res = JSON.parse(JSON.stringify(j, function(key, value) {
return typeof value === "string" ? value.toUpperCase() : value
}));
but this code only capitalizes the very lower level values, not all the keys/values, the reason is because i can only return one value from the replacer function, which is in this case the value.
The replacer function in JSON.stringify, does not allow you to replace keys, as documented in MDN. It allows you to transform values, or to omit key/value pairs altogether (by returning undefined).
Your best bet is probably to transform the object before stringifying it. Underscore or Lodash would make this pretty easy, but you can do it natively without too much trouble like this:
const xform = obj => {
return Object.keys(obj).reduce((xformed, key) => {
let value = obj[key]
if (typeof value ==='string') value = value.toUpperCase()
else if (typeof value === 'object') value = xform(value)
xformed[key.toUpperCase()] = value
return xformed
}, {})
}
console.log(JSON.stringify(xform({a: 'b', c: 1, d: {e: 'f'}})))
// {"A":"B","C":1,"D":{"E":"F"}}
You could also use RegEx and replace after it is stringified if you are so inclined. The code is certainly shorter, but perhaps less readable:
const stringified = JSON.stringify({a: 'b', c: 1, d: {e: 'f'}})
console.log(stringified.replace(/".+?"/g, s => s.toUpperCase()))
// {"A":"B","C":1,"D":{"E":"F"}}
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.