node js why does it collapse object when logged together with string? - javascript

I was doing some basic JSON parsing and wondered why node js collapses the objects when it is logged together with string
so for example in the code below, if I go console.log(processedData) it won't collapse the object and show the whole string but if I go console.log('Body: ' + processedData) it collapses the objects and goes [object Object][object Object].... I know how to expand them again using util but I was curious on the logic behind it as I am quite new to node. I think I might be missing out on something.
const http = require('http');
const util = require('util');
var options = {
host: 'http://nodejs.org/dist/index.json'
// host: 'en.wikipedia.org',
// path: '/w/api.php?action=query&list=allpages&apfrom=Imperial&aplimit=500&format=json'
};
var req = http.get('http://nodejs.org/dist/index.json', function(res) {
console.log('STATUS: ' + res.statusCode);
console.log('HEADERS: ' + JSON.stringify(res.headers));
let body = '';
res.on('data', function(chunk) {
body += chunk;
}).on('end', function() {
let processedData = JSON.parse(body);
console.log('Body : ' + processedData);
console.log(typeof body);
})
});
req.on('error', function(e) {
console.log('ERROR: ' + e.message);
});

When you call
console.log(processedData)
You're passing the entire object to console.log for it to do it's thing. However, when you call
console.log('Body: ' + processedData)
You're passing the result of 'Body: ' + processedData to console.log. The evaluation of this expression causes processedData to be converted to its string representation, which if you haven't defined toString on your object, will just be [object Object], so you see Body: [object Object] being logged.
The simplest way to achieve what you're after is to simply pass them as separate arguments:
console.log('Body: ', processedData)

Maybe we should answer following questions: "If you do the operation like below - what is expected a type of result?"
var myVar = "Body : " + processData;
When js engine tries to evaluate such expression it knows that first parameter of the expression is 'string', so it tries to concatenate the string with another string. How processData become a string? By calling 'toString()' on processData.
To achieve the result you expect, to try to use console.log in that way:
console.log("Body:", processData);

This is because JS type coercion.
In first case you print it as object, but in second, you add it to the string ('Body: ' + processedData) - and according to JS type coercion rules it converts it to string (it concatenates it to string)
You can use util module as you suggested, or to use console.dir({body:processedData},{colors:true,depth:4});

Related

Firebase function - http get parameters with acentuation

I have a firebase function doing a http GET. There are 3 parameters and all works ok but if one of the parameters contains acentuation the Firebase console don't show any error but the the GET is not executed. In this case, the problem is with Parameter03.
var url = 'http://myapi.azurewebsites.net/api/values?Parameter01=' + nameParam + '&Parameter02=' + emailParam + '&Parameter03=' + serviceParam ;
http.get(url, (resp) => {
res.setEncoding('utf8');
}).on("error", (err) => {
console.log("Error : " + err.message);
});
Any help please ?
Whenever you build a URL, you should properly escape all the query string components so that they contain only valid characters. That's what encodeURIComponent() is for. So do encode all your query string values like this instead:
var url = 'http://myapi.azurewebsites.net/api/values' +
'?Parameter01=' + encodeURIComponent(nameParam) +
'&Parameter02=' + encodeURIComponent(emailParam) +
'&Parameter03=' + encodeURIComponent(serviceParam);
There are other cleaner ways to build a URL with query string components, but this should work fine.

AQL Query returns a Promise

I have been trying to get a query result from Arangodb in to my front end service(Angular 4) using soap message. I am able to get a result of the query but printed out in console.log. But how can I get it under this function(myService).
In other words, How can I feed my query result into a function rather than printing out the result in console. So that I can use this function to get the output of the query?
I have used .then() as well in order to get the promise.What am I still missing in it ?
server.js
var myService = db.query(aqlQuery`
LET startVertex = (FOR doc IN spec
FILTER doc.serial_no == '"123456abcde"'
LIMIT 2
RETURN doc
)[0]
FOR v IN 1 ANY startVertex belongs_to
RETURN v.ip`,
{
bindVar1: 'value',
bindVar2: 'value',
})..then(function(res) {
console.log("documents:" + res._result);
})
I would like to feed the function into soap msg and receive it Angular 4,
soap msg
var soap_msg = '<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:examples:CheckUserNameService">' +
'<soapenv:Header/>' +
'<soapenv:Body>' +
'<urn:CheckUserNameResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">' +
'<status xsi:type="xsd:string">' + (myService) + '</status>' +
'</urn:CheckUserNameResponse>' +
'</soapenv:Body>' +
'</soapenv:Envelope>';
var server = http.createServer(function(request,response) {
response.end(soap_msg);
});
var port = 8000;
server.listen(port);
var soapServer = soap.listen(server, '/test', myService, xml);
But the output is either empty braces If I am using JSON.stringify or else it is [object Promise]. What am I doing wrong here ?
output

Remove characters from variable with Javascript

My variable looks as following:
response = "{ tradeofferid: '63341523' }"
I would like to remove all characters except for the letters and the semicolon.
I tried using the replace function but I get some errors.
function(err, response) {
if (err) {
throw err;
}
var result = response;
result = result.replace(/[{}]/g, "");
console.log(offerStatus);
res.end(result);
});
My console points at replace and the error log says: undefined is not a function
What I want to end up with is
response = "tradeofferid: 63341523"
response = { tradeofferid: '63341523' };
alert(response.tradeofferid);
for(var name in response) {
alert(name);
var value = response[name];
alert(value);
}
responseString = name + " : " + value;
alert(responseString);
You may try this but this answer is only specific to your question. This will not work if you have more than one attributes in "response" object.
response = "tradeofferid: " + JSON.parse(response)[tradeofferid]
... if you really want a string for display or something, but I'm guessing you actually just want to parse the JSON and pass the object around but haven't realized it yet.
You need to set something to be replaced in the .replace method. Try with:
var result = response.replace(/[^A-Za-z0-9\: ]/g, "")

window.onerror and [object Event]

I have some errorlogging code on my website that saves Javascript errors to a file so later i can look to se if there is problems with my code in some browsers.
Sometimes i get a error message like message:[object Event] url:undefined line:undefined so i dont know where the error accures.
How do i get more info from message when it is [object Event] so i can know what file and line number the error is from.
window.onerror = error;
function error(message, url, line) {
// sometimes message is [object Event]
}
I am thinks something like this.
window.onerror = error;
function error(message, url, line) {
// sometimes message is [object Event]
if (typeof message === 'object') {
message = message
+ ' + '
+ message.url
+ ' + '
+ message.lineno;
}
}
Trying this but i get Uncaught TypeError: Object # has no method 'serialize'
if (typeof message === 'object') {
message = JSON.serialize(message);
}
With JSON.stringify(message) i get Uncaught TypeError: Converting circular structure to JSON
if (typeof message === 'object') {
message = JSON.stringify(message);
}
In the case where you get something like [someting Something] in JS, it usually means that it is an object. You can do a console.log(message) and inspect the contents of the object. It would look like
{
somethingHere : 'data',
anotherHere : 'more data'
}
To access them, you can do it in the dot notation:
theObject.somethingHere //data
In your case, that would be like this, where something is a key from the object.
message.something
On which browser or browsers are you seeing this [Event object] message occurring? One possible way to inspect the contents of the object is:
var messageString = '';
for (var x in message) {
if (messageString) messageString += ', ';
messageString += x + ': ' + message[x];
}
message = '{' + messageString + '}';
If you can give any kind of reproducible test case for this onerror message, including browser versions on which is happens, that would help a lot.

How do I create a line break in a JavaScript string to feed to NodeJS to write to a text file?

I've created a simple HTML page that takes some input from the user to store on a server to be retrieved later -- this is how the text is treated when the user clicks a submit button (I've placed numbered comments under the key lines but provide the surrounding code for context):
var origText = $('#input-field').val(),
// 1. GETS WHATEVER USER TYPED INTO INPUT FIELD
jsonText = '{ "text": "' + origText + '" }',
// 2. WRAPS IT AN OBJECT STRING
ajaxText = encodeURIComponent(jsonText);
// 3. ENCODES THE STRING FOR USE WITH AJAX
$.ajax({
url: 'http://localhost:8124/',
data: 'save=' + ajaxText + '&fn=save',
// 4. THE ENCODED STRING IS ADDED TO THE QUERY SECTION OF THE AJAX REQUEST
dataType: "jsonp",
cache: false,
timeout: 5000,
success: function(data) {
$("#input-ready").html(data.save.text);
},
error: function(jqXHR, textStatus, errorThrown) {
alert('error ' + textStatus + " " + errorThrown);
}
});
The request is sent to a NodeJS server I am running locally, which (within the http.createServer callback) does the following:
var queryObj = url.parse(req.url, true).query;
// 1. GET THE QUERY PART OF THE REQUEST/URL AS AN OBJECT
res.writeHead(200, {'Content-Type': 'application/javascript'});
// 2. PREPARE SERVER'S RESPONSE AS JAVASCRIPT
queryObj.fn = queryObj.fn || '';
queryObj.save = queryObj.save || '';
queryObj.callback = queryObj.callback || '';
// 3. ENSURE THE PROPERTIES NEEDED ARE DEFINED, EVEN IF FALSE-Y
if (queryObj.fn === 'save') {
// 4. IF THE REQUEST IS TO SAVE THEN WRITE THE USER INPUT AS OBJECT TO A TEXT FILE
fs.writeFile('jsonp-storage-2.txt', queryObj.save, function (err) {
if (err) {
throw err;
} else {
console.log('Saved message successfully.', 'Ready to be read now.');
res.end(queryObj.callback +
'({ fn: "' + queryObj.fn + '", save: ' + queryObj.save + ' })');
}
});
}
Assuming the user types and submits "this is a line of text", the output on the server is a text file called jsonp-storage-2.txt containing this:
{ "text": "this is a line of text" }
After all that, my question is quite simple. How do I prettify the output in the text file?
The code needs work but I'm thinking of using this to try storing larger objects for reading later. However, at the server end, I would like the files (for now) to be easy for me to read when opening them with Notepad, for example.
I have tried using \n and \t like so:
jsonText = '{\n\t"text": "' + origText + '"\n}',
I've also tried \r. But the lines remain unbroken.
Some answers suggest that I can only do this at the level of the encoded string or after the file has been written. Perhaps I missed something simple. Is there a way to do it by manipulating my jsonText variable?
UPDATE:
Just to be clearer about the output desired -- currently the content of the text file produced looks like this:
{ "text": "this is a line of text" }
But I'd like to know if it can be produced like this:
{
"text": "this is a line of text"
}
Use
var os = require('os');
var jsonText = '{' + os.EOL + '\t"text": "' + origText + '"' + os.EOL + '}';
It turns out that when writing a string to a (text) file with Node.js [EDIT: in Windows], use \r\n for a new line.
As with encoded line breaks, both a return carriage and a new line is necessary. So the line of code needed to be this rather than having just \r or just \n:
jsonText = '{\r\n\t"text": "' + origText + '"\r\n}',
The resulting file's content now displays as desired:
{
"text": "this is a line of text"
}

Categories

Resources