LineBreak in console object - javascript

Line break in javascipt string console
console.log("Foo" + "\n" + "Bar");
Line break in javascript object console
console.log({ value : "Foo\nBar" });
Is it possible to add linebreaks in javascript objects.

The answer is no: when you print an object to the console log, strings will be written as javascript objects (similar but not identical to what you'd get if you explicitly converted them into JSON, like console.log(JSON.stringify(object))).
If you want for some reason to print your strings with line breaks, you'd have to implement the object-to-string conversion yourself; perhaps with something like this:
function customString(object) {
let string = '{\n';
Object.keys(object).forEach(key => {
string += ' "' + key + '": "' + object[key] + '"\n';
});
string += '}';
return string;
}
console.log(customString({ value: "Foo\nBar" }));
(It sounds like you have an idea in mind of exactly how you want this output to look, so adjust the function above until it works as expected.)

You can make JSON pretty with automatic line breaks using:
console.log(JSON.stringify({ test: { key: { inner: 'val' } }}, null , 2))
Where 2 is the number of spaces/indent for each level.

You can use ES6:
console.log(`hello
world`)
will produce:
hello
world

I think its originally creating a line break, but due to the object, it's not showing directly. Try to assign it in variable and access that in the console.
Code:
var v = {val:"test\ntest"};
console.log(v.val);
Output:
test
test

Related

Shorthand Shortcircut. Is it possible to do some stuff

This question is about a TypeScript code-base, but the general concepts that underpin it are ECMAScript concepts, therefore; I have tagged the question as both JS & TS. If I should tag it differently, you can either let me know, or make the edit yourself and I will accept it if I see it.
In a TypeScript document, I have defined an object-type that contains 4 string typed properties.
Here is an example of the type
type StrObjType = {
foo?: string;
boo?: string;
fuz?: string;
buz?: string;
}
Along with the object described above, I have a function — its called funkyFunc — with a parameter that takes an argument of type StrObjType.
This is what the function looks like:
function funkyFunc(obj:StrObjType)
{
let mesg = '';
if(obj.foo){ mesg += '\n Foo: ' + obj.foo; }
if(obj.boo){ mesg += '\n Boo: ' + obj.boo; }
if(obj.fuz){ mesg += '\n Fuz: ' + obj.fuz; }
if(obj.buz){ mesg += '\n Buz: ' + obj.buz; }
if(!mesg) return '';
// If a string was concatenated to mesg, return w/ newline appended
return mesg + '\n';
}
About the Function
If you can't tell by looking at it, the function creates a list using only properties that were added to the functions object-argument. The new-lines ('\n') are added as a means to format the list.
You can see in the function that each property in the object's type is checked for a truthy value. When a property is truthy, the props string-value is appended to the mesg variable via the "Addition Assignment Operator".
About the Problem & Solution
What I'd like to know, is if there is a better way to write the if statements, if I can short circuit them, or use a shorthand. Here is an example of a short circuit that uses nullish coalescing. The link shows a short circuit used to check an objects property, and assign it, only if the property is non-nullish (null or undefined). I was hoping to use that operator, but becauese I am appending the value when the property exist, rather than assigning it, the nullish coalescing won't seem to work.
Nevertheless, I can't help but to feel like this is the ideal situation for implementing a short circuit, but if there is a better way to write the function, I can't figure out what it is.
There is this way of writing it, but IDK if it's better.
let mesg = '';
mesg += obj.foo ? '\n Foo: ' + obj.foo : undefined;
mesg += obj.boo ? '\n Boo: ' + obj.boo : undefined;
mesg += obj.fuz ? '\n Fuz: ' + obj.fuz : undefined;
mesg += obj.buz ? '\n Buz: ' + obj.buz : undefined;
if (!mesg) return '';
return mesg + '\n';
}
The problem with the above method of writing the function is that it requires using the JS built-in undefined constant, and that feels hacky to me, as the undefined constant wouldn't be needed otherwise. I could replace the undefined constant with an empty string I guess, but it still doesn't feel right, as it requires adding a nullish value, which are values I typically try to avoid (not that I see any immediate harm that comes from using undefined, or '').
So I guess my question is this...
Is there a shorthand, or short-circuit I can use to eliminate the if keywords in the first function example I added? The short circuit or shorthand cannot be the ternary example I already provided, and it needs to shorten the codes length, or improve the codes readability.
If there is any confusion, or if the question just isn't making sense, let me know, I will clear things up. I am peer reviewed, and I feel like there is something I am missing here. I would like to feel more confident about how I am authoring this function.
There is this way of writing it, but IDK if it's better.
What you have after the text above will result in the string "undfined" appearing in mesg, which I assume you don't want. :-) If you wanted to do it that way, you'd use "", not undefined, for the third operand of the conditional operators:
mesg += obj.foo ? "\n Foo: " + obj.foo : "";
mesg += obj.boo ? "\n Boo: " + obj.boo : "";
mesg += obj.fuz ? "\n Fuz: " + obj.fuz : "";
mesg += obj.buz ? "\n Buz: " + obj.buz : "";
What I'd like to know, is if there is a better way to write the if statements, if I can short circuit them, or use a shorthand.
Not really. Moreover, what you have with the if statements (or the series of conditional operator expressions) is clear and easy to debug. There are other ways to do it, but they may be harder for people coming to the code fresh to understand.
For example, you could have this constant:
const messageParts = [
{key: "foo", label: "Foo"},
{key: "boo", label: "Boo"},
{key: "fuz", label: "Fuz"},
{key: "buz", label: "Buz"},
] as const;
(The as const is important, that way TypeScript can see that the key values are valid keys for StrObjType.)
Then the code is something like:
for (const {key, label} of messageParts) {
const value = obj[key];
if (value) {
mesg += `\n ${label}: ${value}`;
}
}
Playground link
For a one-off, that's definitely not an improvement, and it's certainly not short-circuiting or shorthand. But if there are a lot of places you use this same information, it gives you just one place to maintain it.
But if it's a one-off just to build mesg, I think you're best off with the ifs you already have, or the conditional operator expression alternative you noted (with the undefined => "" fix).

How to invoke javascript in WebView Windows 10 UWP?

I am trying to load a javascript in WebView to do some calculations and get the output in a string. I tried to use following code
string htmlFragment = "<html><head><script type='text/javascript'>" +
"function doubleIt(incoming){ " +
" var intIncoming = parseInt(incoming, 10);" +
" var doubled = intIncoming * 2;" +
" document.body.style.fontSize= doubled.toString() + 'px';" +
" return doubled.toString());" +
"};" +
"</script></head><body>" +
"<div id = 'myDiv'>I AM CONTENT</div></body></html>";
htmlView.NavigateToString(htmlFragment);
htmlView.LoadCompleted += async(s1,e1) =>
{
string result = await htmlView.InvokeScriptAsync("eval", new string[] { "doubleIt(25)" });
Debug.WriteLine(result);
};
Update
I am able to load simple javascript easily now based on help provided in the answer. But now I am facing issues when there is more than one function in javascript, I am getting an exception. I am trying the following code
string htmlFragment = #"<html><head><script type='text/javascript'>" +
"function a(){return 10;};" +
"function b(){return 20;};" +
"function c(){return 30;};" +
"return (a()*b()*c());" +
"</script></head><body>" +
"<div id = 'myDiv'>I AM CONTENT</div></body></html>";
Please suggest.
The documentation for this feature is really poor. It took me some time to figure out how to invoke Javascript in UWP WebView
When you first look at the function call webView.InvokeScriptAsync(string,string[]) your initial reaction is that they want the function name as the first parameter and then the function paramaeters as the string array. (mainly because the MSDN documentation says this)
Parameters
scriptName
Type: System.String [.NET] | Platform::String [C++]
The name of the script function to invoke.
arguments
Type: System.String[]
[.NET] | Platform::Array [C++]
A string array that
packages arguments to the script function.
HOWEVER, this is wrong and will lead to hours of head banging. REALLY, what they want is the word "eval" in the first parameter and then a string array of functions, and or commands you wish to eval
var value = await webViewer.InvokeScriptAsync("eval",
new string[]
{
"functionName(functionParams)"
});
Having worked with Microsoft APIs for a few years now I am convinced that this is not the intended way of consuming this function and is a bit of a hack. Unfortunately if you want to consume JavaScript this is the only way that I know that works currently.
Anthony,
Try to check your own suggestion:
await webViewer.InvokeScriptAsync("eval",
new string[]
{
"functionName(functionParams)"
});
or:
await webViewer.InvokeScriptAsync(functionName, new string[]{ functionParameters });
The same as Microsoft suggests, just you are limiting a function name by one ("eval") - not necessary. Trust me, you can use any function name, as I am now with UWP and before with windows phone hybrid apps.
The question is already 4 years old, but I'm coming to see why you were getting an empty string as a result.
In your example, the functions in JavaScript return integers while the expected value is of type string.
By modifying these functions and returning a string like this:
string htmlFragment = #"<html><head><script type='text/javascript'>" +
"function a(){return '10';};" +
"function b(){return '20';};" +
"function c(){return '30';};" +
"</script></head><body>" +
"<div id = 'myDiv'>I AM CONTENT</div></body></html>";
We get the good result on the way back.

Using json objects in duktape

everybody. I've just integrated duktape in my c++ code so that I'm able to use javascript.
But the problem I can't solve right now : how to use json objects in javascript.
Assume I've got some javascript like
function hi(person) {
print ('hi, ' + person.name );
}
And json object :
{
'name' : 'duktape'
}
So now I need to call function hi with an argument of this json in my cpp code.
duk_eval_string(ctx, "function hi(person) {print ('hi, ' + person.name );}");
duk_push_global_object(ctx);
duk_get_prop_string(ctx, -1, "hi" ); // pushes function from loaded script to stack
auto json = "{'name' : 'duktape' }";
duk_push_string(ctx, json);
duk_pcall(ctx, 1);
The output I get tells, that object is not correct
hi, undefined
Would like to head any suggestions on who should be done to get it working! Thank's for your time :)
You need to use duk_json_decode:
char *json = "{\"name\": \"duktape\"}";
duk_push_string(ctx, json);
duk_json_decode(ctx, -1);
duk_pcall(ctx, 1);
duk_pop_2(ctx);
Output:
hi, duktape
Note that your original json is not valid, you need to use " as string delimiters instead of '.
Depending on what you really needs, you could also create the object manually:
duk_idx_t obj_idx = duk_push_object(ctx);
duk_push_string(ctx, "duktape");
duk_put_prop_string(ctx, obj_idx, "name");
duk_pcall(ctx, 1);
duk_pop(ctx);

How to customize JSON output on the first level ONLY using JavaScript's stringify() method?

I use stringify() method in JavaScript to convert a list of objects to a string, but I need to customize the output on the first level ONLY like the following:
[
/*T01*/ {"startX":55,"endX":109,"sartY":0,"endY":249},
/*T02*/ {"startX":110,"endX":164,"sartY":0,"endY":249},
/*T03*/ {"startX":165,"endX":219,"sartY":0,"endY":249},
/*T04*/ {"startX":220,"endX":274,"sartY":0,"endY":249},
/*T05*/ {"startX":275,"endX":329,"sartY":0,"endY":249},
/*T06*/ {"startX":330,"endX":384,"sartY":0,"endY":249},
/*T07*/ {"startX":385,"endX":439,"sartY":0,"endY":249},
/*T08*/ {"startX":440,"endX":494,"sartY":0,"endY":249},
/*T09*/ {"startX":495,"endX":549,"sartY":0,"endY":249},
/*T10*/ {"startX":550,"endX":604,"sartY":0,"endY":249}
]
Now there are other parameters in stringfy() method, replacer and space, can't I use them to format my output like the aforementioned format including:
tabs
spaces
comments
You are not going to get JSON.parse to make that output since it is not valid JSON. But if you want to have something rendered like that, it is a simple loop and string concatenation.
var details = [
{"startX":55,"endX":109,"sartY":0,"endY":249},
{"startX":110,"endX":164,"sartY":0,"endY":249},
{"startX":165,"endX":219,"sartY":0,"endY":249},
{"startX":220,"endX":274,"sartY":0,"endY":249},
{"startX":275,"endX":329,"sartY":0,"endY":249},
{"startX":330,"endX":384,"sartY":0,"endY":249},
{"startX":385,"endX":439,"sartY":0,"endY":249},
{"startX":440,"endX":494,"sartY":0,"endY":249},
{"startX":495,"endX":549,"sartY":0,"endY":249},
{"startX":550,"endX":604,"sartY":0,"endY":249}
];
var out = "[\n" + details.map(function(val, i) {
var id = "\t/*T" + ("0" + (i + 1)).substr(-2) + "*/\t";
return id + JSON.stringify(val);
}).join(",\n") + "\n]";
console.log(out);

Why does eval() give undefined value in Javascript?

I am working in JavaScript coding. I have created a text area with name OQ_0 and value "0". When i use eval() method for that field in JavaScript it is giving the value undefined. The below are the part of JavaScript code
var tempOpenQtyStr = "document.InitiateReturnsForm.OQ" + "_" + 0;
var tempOpenxQtyStr = eval(tempOpenQtyStr).value;
alert('Manuals =' + document.InitiateReturnsForm.OQ_0.value);
alert('eval(tempOpenxQtyStr ) =' + eval(tempOpenxQtyStr));
alert('eval(tempOpenxQtyStr).value =' + eval(tempOpenxQtyStr).value);
Output:
Manuals = 0
eval(tempOpenxQtyStr ) = 0 --- Here it is suppose to show "[object]"
eval(tempOpenxQtyStr).value = undefined.
Kindly help me out what is change to do. Thanks in advance.
Why not just use document.InitiateReturnsForm["OQ_" + 0].value?
Try
alert('eval(tempOpenxQtyStr ) = ' + eval(tempOpenQtyStr));
alert('eval(tempOpenxQtyStr).value = ' + eval(tempOpenQtyStr).value);
In the second and third alert you are evaluating the second variable which stores the value of the first evaluated object. That's why the error occurs.
alert('eval(tempOpenxQtyStr ) =' + eval(tempOpenxQtyStr));
Since you put a string, not an object, inside tempOpenxQtyStr, it evaluates that string and returns 0.
alert('eval(tempOpenxQtyStr).value =' + eval(tempOpenxQtyStr).value);
Here you're using a method on a variable that contains a string. That doesn't work. It doesn't have that method, that's why it returns undefinied.
You might want to try doing eval(tempOpenxQtyStr.value) instead of eval(tempOpenxQtyStr).value since the last one does basically nothing, just evaluating an object and then fetching the objects value (it doesn't eval the value itself).

Categories