How do I show console.log output in an alert - javascript

If I create an object and use console.log it will expand the object and I can see the object properties. If I use alert it does not. Is there any way to do the same thing in an alert?
car=new Object();
car.wheels=4;
car.make="honda";
car.owner="me"
console.log(car);
output: Object { wheels: 4, make: "honda", owner: "me" }
alert(car)
output is [object Object]
How can I get the same output for the alert?

As others have stated you use JSON.stringify.
But I wanted to give a few other pointers. I don't know if you know these already, but your example indicated that you might appreciate the tips.
In JavaScript it is recommended to not use new Object() Instead just create your object:
var car = {
wheels: 4,
make: "honda",
owner: "me"
}
Always use var, let or const when creating variables. If you don't then they are created on the global scope. In the browser you would be creating the new variables on the window object.
JSON.stringify has other parameters:
JSON.stringify(value[, replacer[, space]])
The replacer is not often used, but it can provide a way of filtering and preventing recursive data.
The space parameter can be a number form 0 to 10 or a number of characters in a string from 0 to 10. This indicates how much to indent each level in the output.
function replacer(key, value) {
if (typeof value === 'string') {
return undefined;
}
return value;
}
var foo = {
company: 'Sony',
model: 'Playstation',
version: 4,
pricing: [
{
pro: false,
price: 299.00
},
{
pro: true,
price: 399.00
}
],
comments: 'none'
};
alert(JSON.stringify(foo, replacer, 2));
alert(JSON.stringify(foo, replacer, '----'));

In the console log method, the parameter is considered as an object. So, the object can be in any form like an array, string, integer, etc., and We will get the content. But in the alert method, it accepts only the string. So, if you send the object, it will convert it as string version of the object ( object Object ). If you stringify the object and send as a parameter to the alert method, it will display the content. Try this one,
window.alert(JSON.stringify(object));

You can use this alert(JSON.stringify(object))

Related

Objection.js not proper return

i am not getting proper the return after insertgraph in objection.js
i am getting the result like :
[
User {
name: 'Santosh Devi',
city: 'Suratgarh',
number: '9898987458',
userroles: UserRoles { role_id: 2, user_id: 37 },
id: 37
}
]
where i want the result like :
[
{
name: 'Santosh Devi',
city: 'Suratgarh',
number: '9898987458',
userroles: { role_id: 2, user_id: 37 },
id: 37
}
]
There are few ways to get rid of the specific class references:
1. JSON.parse(JSON.stringify(result))
This will rebuild the object by first converting the whole object to a string (in JSON format), and then by doing the reverse -- creating a new object from a string. As this string format (JSON) does not store custom class information, it achieves your purpose. However, if your object has functions, symbols, then these will be omitted. Also Map and Set will become empty objects. For a more complete list of restrictions. See JSON.stringify
2. Deep Clone
There are several deep-clone functions out there, that may or may not do what you expect. Some will still try to maintain the original prototype references, so that it would not benefit you. You can find some here: How to Deep clone in javascript. For your case, this one would do the job:
function deepClone(obj, hash = new WeakMap()) {
if (Object(obj) !== obj) return obj; // primitives
if (hash.has(obj)) return hash.get(obj); // cyclic reference
const result = Array.isArray(obj) ? [] : {};
hash.set(obj, result);
return Object.assign(result, ...Object.keys(obj).map(
key => ({ [key]: deepClone(obj[key], hash) }) ));
}
You call it as newResult = deepClone(result).
The advantage here, is that it supports cyclic references, which JSON.stringify cannot handle. Also, there is no string conversion happening, which really is not necessary. You can extend this function to keep deal with some class instances that you like to stay that way. See how you can support Date, RegExp, Map, Set, ... in this answer. But don't do the "catch-all" line.
3. Change the prototype
With this strategy you mutate the result in-place.
function removeClasses(obj, hash = new WeakSet()) {
if (Object(obj) !== obj) return; // primitives
if (hash.has(obj)) return; // cyclic reference
hash.add(obj);
if (Array.isArray(obj)) Object.setPrototypeOf(obj, Array.prototype);
else Object.setPrototypeOf(obj, Object.prototype);
for (let value of Object.values(obj)) {
removeClasses(value, hash);
}
}
Call it as removeClasses(result), and afterwards result will have been "fixed". Again, this method does not use a conversion to string. As it does not create a new object either, it consumes less memory. But on the other hand you mutate an object, and some would advise against that.

How to grab the children of an Object.keys(myEl) reference

In the code below, I can get a reference to the text000 object, but I need to capture its child array as my target payload. Once I have a reference to the key, how can I capture its children?
Full object is below:
activeItem = [{"dnd":{"index":0,"active":true,"group":"common","label":"Text (000)","type":"text"},
"json":{"schema":{"properties":{"text000":{"title":"Text (000)","type":"string"}},"required":["text000"]},"layout":[{"key":"text000","description":"","floatLabel":"auto","validationMessages":{"required":"Required"}}]}}]
To grab a reference to the "text000" key I'm using:
const myEl = Object.keys(this.activeItem.json.schema.properties); // points to text000
I need to pull that key's contents/children > {"title":"Text (000)","type":"string"} out to use it as my target payload for this operation.
The text000 element is dynamic so I need its reference, which is why I'm using the Object.keys() method to point to it.
Feel free to school me on the proper names to use to refer to these elements. For example, not sure exactly how to reference > {"title":"Text (000)","type":"string"} with respect to the key text000. Is that the key's "children", "value", "contents" or what?
UPDATE:
console.log('TRY: ', this.activeItem.json.schema.properties[0]);
// Returns undefined
console.log('TRY2: ', this.activeItem.json.schema.properties);
// Returns {"text000":{"title":"Text (000)","type":"string"}}
I need something to return:
{"title":"Text (000)","type":"string"}
SOLUTION thanks #jaredgorski:
const properties = this.activeItem.json.schema.properties;
const propertiesKeys = Object.keys(properties);
const propertiesKeysFirstVal = Object.keys(properties)[0];
const logProperties = properties[propertiesKeysFirstVal];
console.log('PROPERTIES KEYS:', propertiesKeys);
console.log(
'VALUES OF FIRST PROPERTIES KEY:',
propertiesKeysFirstVal
);
console.log('RESULT:', logProperties);
PROPERTIES KEYS: ["text000"]
wrux-wrux-form-builder.js:1782 VALUES OF FIRST PROPERTIES KEY: text000
wrux-wrux-form-builder.js:1783 RESULT: {title: "Text (000)", type: "string"}
You need to remember that activeItem is an array. As long as you include the index (in this case the first index, which is [0]), you can access the json property (or key) and continue down the chain to retrieve the values in text000.
The other trick here is that you're wanting to access the first key in properties, but you don't know the name of that key yet. So what you need to do is actually make an array of the keys and then find out the name of the first key in that properties object. To do this, you can use Object.keys(), a method which turns the keys of an object into an array. Once you have the name of this key, you only need to use bracket notation on the properties object to find the value for this key. I'll show you how this works in the snippet below.
Here are some references so that you can learn more about how this works:
MDN page on the Object.keys() method
Accessing JavaScript
object properties: Bracket notation vs. Dot notation
And here's the working example:
const activeItem = [
{
"dnd": {
"index": 0,
"active": true,
"group":"common",
"label":"Text (000)",
"type":"text",
"icon":"text_fields",
"fontSet":"material-icons",
"class":""
},
"json": {
"schema": {
"properties": {
"text000":{
"title":"Text (000)",
"type":"string"
}
},
"required":["text000"]
},
"layout":[
{
"key":"text000",
"description":"",
"floatLabel":"auto",
"validationMessages": {
"required":"Required"
}
}
]
}
}
]
// This is the dirty looking version:
const logPropertiesDirty = activeItem[0].json.schema.properties[Object.keys(activeItem[0].json.schema.properties)[0]]
console.log("First, the dirty version where we don't save anything to variables. Everything is laid out here.")
console.log('WHAT WE DID:', 'activeItem[0].json.schema.properties[Object.keys(activeItem[0].json.schema.properties)[0]]')
console.log('RESULT:', logPropertiesDirty)
console.log('=================================================')
// This is the cleaner version, using variables to store things as we go:
const properties = activeItem[0].json.schema.properties;
const propertiesKeys = Object.keys(properties);
const propertiesKeysFirstVal = Object.keys(properties)[0];
const logPropertiesClean = properties[propertiesKeysFirstVal];
console.log('Now, the cleaner version. We save some values to variables to make things more readable.')
console.log('PROPERTIES OBJECT:', properties)
console.log('PROPERTIES KEYS:', propertiesKeys)
console.log('NAME OF FIRST PROPERTIES KEY:', propertiesKeysFirstVal)
console.log('RESULT:', logPropertiesClean)
Regarding what to call these things, I've always thought of Objects as generally consisting of "key-value pairs". Keys can also be called properties and values can also be called contents (I guess).
myObject = {
key1: value1,
property2: contentsOfProperty2
}
At the end of the day, clear communication is all that counts! So, whatever names you come up with (as long as they make reasonable sense), I'm sure people won't be jerks about it unless they feel like they have something to prove.
You should be able to use Object.values over this.activeItem.json.schema.properties:
The Object.values() method returns an array of a given object's own enumerable property values, in the same order as that provided by a for...in loop (the difference being that a for-in loop enumerates properties in the prototype chain as well).
const object1 = {
a: 'somestring',
b: 42,
c: false
};
console.log(Object.values(object1));
// expected output: Array ["somestring", 42, false]
It is not supported across the map yet, but you should be able to load a polyfill if you need it.

Javascript: Convert code string and back

Suppose that I have this code:
var cfg = {
config: {
fields: {
name: {
type: 'text'
},
age: {
type: 'number'
}
},
actions: [
{
label: 'Print',
cb: (model) => {
console.log(model);
}
}
]
},
data: {name: 'Jhon', age: 23}
}
And I want to convert it to a string (to let a user edit it) and then convert it back to executable code, any idea in how to achieve this?
I tried with JSON.stringify and JSON.parse but that will of course strip the functions. .toString returns "[object Object]", iterating on the object and call .toString when the values is a string, function or number is a possibility, any other idea?
The Function constructor takes code as string, so does eval and a couple other. However, if in any way avoidable, do not convert code to string and backwards because of security concerns, ability to debug and a lot of other issues you can run into when doing so.
Converting code to a string is slightly annoying, because you need to make sure you don't redeclare variables and everything in the new context is syntactically correct, e.g. note that obj's f property is again named in the declaration, because it is later given to eval which places it in the global scope where it needs a name.
let obj = { f: function f() { let stuff = "hi"; console.log("hi"); } };
let code = obj.f.toString();
console.log(code);
eval(code);
f();
Note that JSON.stringify has an optional replacer parameter which can be used to customize the process.
I will again highly advise to avoid any code to/from string conversions when possible, in all normal cases this is not needed and should not be done.
You can iterate around that object and set it to inputs elements, like this
for (var key in cfg.config.fields) {
console.log(key, cfg.config.fields[key].type);
console.log(key, cfg.data[key],'data');
console.log('<input type="'+cfg.config.fields[key].type+'" value="'+cfg.data[key]+'">')
}
This is the solution I came up with:
const toString = (code) => {
if(Array.isArray(code)){
return code.map(item => toString(item));
}
else if(typeof code == 'object'){
let tmp = {};
Object.keys(code).forEach(key => {
tmp[key] = toString(code[key])
});
return tmp;
}
else{
return code.toString().split('\n').join('').replace(/ +(?= )/gmi, '');
}
};
This will iterate recursively across all the properties in a random JS structure (an object containing objects and arrays) an return the corresponding structure containing strings, you can then use JSON.stringify to get the actual string.
After the user edited it, it is executed with:
eval(`(${string})`);
As noted by other, be careful using eval, it can be dangerous (an interesting article is https://www.nczonline.net/blog/2013/06/25/eval-isnt-evil-just-misunderstood/)

Javascript array push only if value not null

I'm wondering if, and if how the following thing is working:
I have an array defined like the following:
var array = [
{number: '1', value: 'one', context: 'someContext'},
{number: '2', value: 'two', context: 'anotherContext'},
...
]
What I'm currently doing is pushing the elements into the array, so array.push({number: '1', value: 'one', context: 'someContext'}); and so on, with every array element.
Now this thing is extended: Say there's another key called 'content'. This key has a appropriate value, that is either undefined or a string. Now the question is: If I put the pushing in a function like this:
push(number, value, context, content) {
array.push({
number: number,
value: value,
context: context,
content: content
})
}
Is there anyway, I can make sure, that the key content is only added to the element, if the content (the function gets as parameter) is not null.
Of course I can modify function like that:
push(number, value, context, content) {
if(!content) {
array.push({
number: number,
value: value,
context: context,
content: content
})
} else {
array.push({
number: number,
value: value,
context: context
})
}
}
But the question is, if there is anyway to do this in the push function. I also thought about something like
array.push({
number: number,
value: value,
context: context,
content? content: content
})
So it would only be inserted if content is defined, but does this work, it didn't seem like, but maybe theres a mistake in my code.
If the objective isn't just to make code shorter, the most readable would be something like this, where you create the object, add the property if there is a value, and then push the object to the array.
push(number, value, context, content) {
var o = {
number : number,
value : value,
context : context
}
if (content !== null) o.content = content;
array.push(o);
);
Here's an ES6 way to construct the object directly inside Array.push, and filter any that has null as a value.
function push(...arg) {
array.push(['number','value','context','content'].reduce((a,b,i)=> {
if (arg[i] !== null) a[b]=arg[i]; return a;
}, {}))
}
With Spread operator for object literals (ECMAScript 2018) it looks super easy:
const myPush = (number, value, context, content) =>
array.push({
...{ number, value, context },
...content && { content }
});
If you are open to using ES2015, this can be done with Object.assign:
array.push(
Object.assign(
{ number, value, context },
content ? { content } : null
)
);
It can be done by extending array:
//create Your own array object
myArray=function(){};
myArray.prototype=Object.create(Array.prototype);
//create method
myArray.prototype.pushDefined=function(obj){
var newObj={};//create clean object
for (var key in obj){
if (typeof obj[key]!='undefined' && obj[key]!=null){
//this element is defined and is not null
newObj[key]=obj[key];
}
}
this.push(newObj);//push clean object without undefind properties
};
//tests
var arr=new myArray();
arr.pushDefined({ name:"John",surname:null});
console.log(arr[0]);
Or add this method to Array prototype:
Array.prototype.pushDefined=function(obj)... //this will be method in every array
I would not recommend changing original push method in Array because
always think about other programmers who are using Array in this
particular project.

Nested objects overwriting each other

I'm having some issues with what would seem to me a fairly simple datastructure. I have an object called mylist with 1. an nested empty {} in it and 2. a function to add objects into (1). Please consider the following code:
var object1 = {name: "Object_1"}
var object2 = {name: "Object_2"}
var mylist = {
list: {},
add: function(item, val){
this.list[item] = val
}
}
mylist.add(object1,5)
mylist.add(object2,10)
console.log(mylist)
Now, I would expect the output to be
{ list: { object1: 5, object2: 10 }, add: [Function] }
But instead what I get is:
{ list: { '[object Object]': 10 }, add: [Function] }
For some reason, previous objects in the list are overwritten. Also there seems to be some sort of a conversion to string happening (because of the quotation marks), but I'm not sure why. Why am I not getting the output I expect? Does anyone has a good resource on this?
Thanks a lot in advance.
Maurits
this is because you are passing an object not a string, so whenever you do this:
mylist.add(object1,5);
instead of passing the object object1, you should pass a string:
mylist.add(object1.name,5);
this will return:
{ list: { "Object_1": 5 }, add: [Function] }
otherwise if you do not send a string whatever you pass will be converted into a string
The problem was when you add a property to a object like this.list[item] JavaScript implicitly converts the property into String using toString()(JavaScript properties have keys a strings).
Now when running toString() on object1 and object2 the result is [Object object]. So when first object is added to list it's key becomes [Object object]. When second object is added, it will also have same key [Object object], hence will overwrite the previous one.
So to make the your code working just add .name to item.
var object1 = {name: "Object_1"};
var object2 = {name: "Object_2"};
var mylist = {
list: {},
add: function(item, val){
this.list[item.name] = val;
}
}
mylist.add(object1,5);
mylist.add(object2,10);
console.log(mylist.list);

Categories

Resources