Firebase function - http get parameters with acentuation - javascript

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.

Related

Can sql queries vary by coulmns?

I'm trying to allow users to add routes to points on a leaflet map, using sql queries to a database of points. Because I want each point to have more than one route that passes through it, I added additional columns: "route2", "routenumber2" till "route5", "routenumber5" to the original "route" and "routenumber".
The following code does work, but I figured it's repetitive to write it out five times, each time only with a different set of columns.
if (e.target && e.target.id == "submitrest") {
const enteredRoute = document.getElementById("input_Route").value; // from user form input
const enteredNumber = document.getElementById("input_routenumber").value;
const enteredNickname = document.getElementById("input_nick").value;
const enteredID = document.getElementById("input_cartodb_id").value;
cartoData.eachLayer(function (layer) {
// SQL to put layer in -- Building the SQL query
let sql =
"UPDATE stops " +
"SET area = '" + enteredRoute + "', " +
"route_number = '" + enteredNumber + "', " +
"nickname = '" + enteredNickname + "' " +
"WHERE cartodb_id = " + enteredID + ";"
console.log(sql);
if (enteredRoute && enteredNickname && enteredNumber && enteredID) {
fetch(url1, {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
body: "q=" + encodeURI(sql)
})
.then(function (response) {
return response.json();
})
.then(function (data) {
console.log("Data saved:", data);
})
What I am asking is if, like how document.getElementById allows the user to input different data each time and send the data using the same code, there is a less repetitive way to make an sql query function that allows me to put the data into "route3" and "routenumber3" if "route2" and "routenumber2" are already full, and so on.
What I would like is a row in CartoDB to have five sets/columns routes and routenumbers that a user can input data to, preferably with less duplicated code.
So far I've tried using Javascript class constructors and the Factory Method. Can I get these to allow the the columns specified in the sql query to be variable? Thank you

Outlook JS Add-in: EWS Calls using Ajax and Callback Token

The Office JS API has a 1 Mb limit on callbacks, and one of the requirements I have is to forward an existing email, designated as spam by the user, as an attachment to a 3rd party. I have extensive code to handle mail operations, using makeEwsRequestAsync, and for this case SOAP that works fine to return the MIME content to create and send the email, but not when the callback return is larger than 1 Mb.
To get around the 1 Mb limitation, it was suggested to others to make the EWS call directly, using a callback token, an item Id, and the EWS URL. I can easily get these components, and I have SOAP that works for the usual makeEwsRequestAsync method.
What I don't have is how to make the call to EWS call with the elements I have.
As an example, I used the following to get the EWS URL and item Id:
_mailbox = Office.context.mailbox;
_ewsUrl = _mailbox.ewsUrl;
var item = _mailbox.item;
_itemId = item.itemId;
I use this to get the callback token:
mailViaEws.Authenticate = function Start() {
getCallbackToken(setCallbackToken);
};
function getCallbackToken(callback) {
var options = {
isRest: false
};
Office.context.mailbox.getCallbackTokenAsync(options, callback);
}
function setCallbackToken(asyncResult) {
if (asyncResult.status === "succeeded") {
_callbackToken = asyncResult.value;
} else {
app.showNotification(_appName, asyncResult.error.message);
}
}
The SOAP is as follows, with a helper method to wrap the SOAP:
var soapToCreateItem =
'<soap:Body>' +
' <m:CreateItem MessageDisposition="SendAndSaveCopy"' +
' xmlns="http://schemas.microsoft.com/exchange/services/2006/messages" ' +
' xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">' +
' <m:Items>' +
' <t:Message>' +
' <t:Subject>' + _subject + '</t:Subject>' +
' <t:Body BodyType="Text">' + _bodyText + '</t:Body>' +
' <t:ToRecipients>' + _adddressesSoap + '</t:ToRecipients>' +
' </t:Message>' +
' </m:Items>' +
' </m:CreateItem>' +
' </soap:Body>';
var soapToCreateItemData = getSoapBoadyEnvelope(soapToCreateItem);
I've search extensively, and although I've found code that use an intermediate service to call the EWS Managed API in C#, I am trying to make the call directly to EWS. Any help would be greatly appreciated.
Your Mailbox (_mailbox = Office.context.mailbox;) object has a method makeEwsRequestAsync that you can use to make SOAP call to the EWS.
Note, that you don't need to provide access token explicitly.
Here is more information.
The Callback token you get from getCallbackTokenAsync is only good for 5 minutes and is only good for the GetAttachment and GetItem EWS operations this is documented in https://learn.microsoft.com/en-us/office/dev/add-ins/reference/objectmodel/requirement-set-1.5/office.context.mailbox so your CreateItem request won't work in this context. Does the message need to come from the user if it just SPAM reporting? it would be easy just to do the send part using a Service Account with EWS or even just send it via SMTP.

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

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});

UserCannotBeAlteredWithoutSessionError when updating PFUser on Parse from Heroku node.js app

I'm trying to update a PFUser in my Parse database from a node.js app running on Heroku. I'm calling the Parse cloud function from an iOS app.
Here's the part of the code I use to update the user on parse as well as creating the user on Stripe (the Stripe part works fine):
Parse.Cloud.define("createCustomerWithCreditCardToken", function(request, response) {
var userId = request.user.id;
var sourceId = request.params.creditCardToken;
var customerId;
var userSessionToken = request.user.getSessionToken();
console.log('userId: ' + userId + ' source: ' + sourceId + ' userSessionToken: ' + userSessionToken);
stripe.customers.create({
source: sourceId,
description: userId
}, function(error, customer) {
if (error !== null) {
response.error('error creating customer: ' + error);
}else {
var userQuery = new Parse.Query('User');
userQuery.equalTo('objectId', userId);
userQuery.first({sessionToken: userSessionToken}).then(function(user) {
console.log('user from parse query: ' + user.get("username"));
user.set("stripeCustomerId", customer.id);
user.save(null, {
success: function(parseCustomer) {
console.log('customer saved to parse: ' + parseCustomer);
},
error: function(error, parseCustomer) {
console.log('customer save failed: ' + JSON.stringify(error, null, 2) + ' with error: ' + JSON.stringify(parseCustomer,null, 2));
}
});
});
customerId = customer.id;
console.log('customerId: '+ customerId);
// response.success(customer);
response.success('Customer: ' + JSON.stringify(customer, null, 2) + 'error: ' + error);
}
});
});
I get the following error log output when I run this:
error log output
error: { "code": 206, "message": "Parse::UserCannotBeAlteredWithoutSessionError" }
In this post the current user concept in a node.js app context is discussed by a Parse engineer.
Also in Cloud Code, the concept of a method that returns the current
user makes sense, as it does in JavaScript on a web page, because
there’s only one active request and only one user. However in a
context like node.js, there can’t be a global current user, which
requires explicit passing of the session token.
Essentially he advises to do this:
Parse.Cloud.define('findBacon', function(req, res) {
var token = req.user.getSessionToken();
var query = new Parse.Query('Bacon');
// Pass the session token to the query
query.find({ sessionToken: token }).then( ... );
});
I have also tried using {useMasterKey:true} instead of {sessionToken:userSessionToken} which produces the same error.
I might just be missing some obvious detail, but I just can't seem to find it. Any ideas on how to solve this are greatly appreciated.
Turns out there's a third way of handling credentials:
Parse.Cloud.useMasterKey();
I placed this line in the beginning of the entire method, that did it for me. I'm not sure of the implications of giving the whole function these credentials though.
I'm not sure when you would use the other options either.
If someone comes across this and would like to elaborate, I'll be happy to give the right answer to a good explanation of when to grant which credentials.

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