passing non-url encoded parameters to an ajax call in node.js - javascript

I am trying to pass parameters from my website to a couchdb server through a node.js server.
I absolutely need to pass {} in a url. Not a string, not an empty object, the actual {} characters. It is used to define the end_key parameter in couchdb views.
At the moment, my call goes like this :
let url = "/trades";
let ajax_options = {
data:{
design_name:'bla',
view_name:'blabla',
params_view:{
group_level:2,
start_key:["1",0],
end_key:["1",{}]
}
}
};
$.ajax(url,ajax_options).then((res) => { ... });
when it passes through NodeJs and the nano library with
db.view(req.query.design_name, req.query.view_name, req.query.params_view)
the end_key object in params_view becomes ["1"] instead of ["1",{}] which I would like to see.
I have verified that with the correct value for end_key, the view gives me the expected result.
How to prevent that behavior from occurring ?

Related

Parse a string representation of javascript without storing a file

There is a scenario where I let a client to insert a JavaScript script that should be sent my server. Actually, this script (well, should..) will export some object.
So the frontend code is something like this:
<form action="/blabla.js" method="post">
<textarea>
</form>
Then the frontend sends the input of the <textarea /> to the server.
A typical input will be something like:
module.exports = {
glagla: {
blabla: 2
},
};
The frontend will send this script, as a string, to a server.
Next step is the server needs to parse this string.
So right now, for example with express package it should look like:
import fs from 'fs';
const handler = async (req, res) => {
const input = req.body.script;
await fs.promises.writeFile('./somewhere.js', req.body.script);
const parsedObject = require('./somewhere.js');
}
I'm trying to not use the file system, but cannot find a way to do so.
I there a pure way, without using the file system to parse such a script in JS?
I think this package https://www.npmjs.com/package/vm2 is the solution.
Basically you don't need to use module.exports for this, because you dont need to create file and then include it in the code with require. You can pass just function body:
// String from frontend, which must
// contain function body
const strFn = 'return { glagla: { blabla: 2 }}';
// Create function from string
const obj = new Function(strFn);
// Run created function and access
// property of returned object
console.log(obj().glagla.blabla);
But keep in mind, that this is pretty risky, because user can pass anything from frontend to your backend to run.
If you need to pass only object with it's properties and values, it's better to utilize JSON for this purpose:
// Object on frontend side
const frontendObj = { glagla: { blabla: 2 }};
// While on frontend, convert object
// in to the JSON string
const strJSON = JSON.stringify(frontendObj);
//
// Then send this string to the server
//
// On server side parse received JSON
// string in to the JS object
const obj = JSON.parse(strJSON);
// Now you can access property of
// returned object
console.log(obj.glagla.blabla);

Can placeholders be used only for Database Events in Firebase and not queries?

Take a look at the following JSON structure:
"Fund_Project_Request" : {
"-LEEy7uxXEeI4AJuePoB" : {
"4ZpTt0rHvjYfKAnCukIlhGpH6kz2" : {
"afds1234" : 2,
"asdf12" : 2
},
"iRfNzDSjFiOADqn3KsG8nNuZEfp2" : {
"afds1234" : 1
}
}
},
Here, if I want to get the values 'afds1234' or 'asdf12' which I'm going to call as 'reward_ids' in an onWrite function, all I have to do is:
exports.manipulateRewards = functions.database.ref('/Fund_Project_Request/{ArtcallID}/{UserID}/{rewardID}').onWrite((change, context) => {
const reward_id = context.params.rewardID;
});
Let's say I want to obtain these reward_ids strings without using the onWrite function. Would I be able to do so with a singleValueEventListener or any other method of querying?
When writing code to query Realtime Database, there are no wildcards. You must know the exact path of the data you're interested in.
Cloud Functions triggers aren't really anything like normal listeners. They are essentially filtering all writes that flow through the system, and triggering only on the writes that match the given path.

API Connect - 500 error when including basic Javascript

I'm trying some basic API Connect tutorials on IBM's platform (running locally using loopback) and have got completely stuck at an early point.
I've built a basic API service with some in-memory data and setter / getter functions. I've then built a separate API which takes two GET parameters and uses one of my getter functions to perform a search based on two criteria. When I run it, I successfully get a response with the following JSON object:
[{"itemId":1,"charge":9,"itemSize":2,"id":2}]
I've then tried to add a piece of server logic that modifies the response data - at this point, I'm just trying to add an extra field. I've added a Javascript component in the Assemble view and included the following code (taken from a tutorial), which I thought should modify the message body returned by the API while still passing it through:
//APIC: get the payload
var json = apim.getvariable('message.body');
//console.error("json %s", JSON.stringify(json));
//same: code to inject new attribute
json.platform = 'Powered by IBM API Connect';
//APIC: set the payload
//message.body = json;
apim.setvariable('message.body', json);
Instead of getting an extra JSON parameter ("platform"), all I get is a 500 error when I call the service. I'm guessing that I'm doing something fundamentally wrong, but all the docs suggest these are the right variable names to use.
You can't access json.platform but at that point json variable is json type. Are you sure that you can add a property to a json type variable if your json object lacks of that property? I mean: What if you first parse the json variable of json type to a normal object, then add new property, and finally stringify to json type again for body assigning purposes?
var json = JSON.parse(apim.getvariable('message.body')); //convert to normal object
json.platform = 'Powered by IBM API Connect'; //add new property
apim.setvariable('message.body', JSON.stringify(json)); //convert to json again before setting as body value
You need to get the context in some determined format, and in this function do your logic. For example if your message is in json you need to do:
apim.readInputAsJSON(function (error, json) {
if (error)
{
// handle error
apim.error('MyError', 500, 'Internal Error', 'Some error message');
}
else
{
//APIC: get the payload
var json = apim.getvariable('message.body');
//console.error("json %s", JSON.stringify(json));
if(json){
//same: code to inject new attribute
json.platform = 'Powered by IBM API Connect';
//APIC: set the payload
//message.body = json;
apim.setvariable('message.body', json);
}
}
});
Reference:
IBM Reference
You have the message.body empty, put a invoke/proxy policy before your gateway/javascript policy for example.

Interpolate string with dynamic data with angular2

I'm loading up data from the server via ajax requests. The JSON file has configurations for popups in the site.
popupData: {
data:{ var_one: "hello", var_two: "world"},
template: "the <b>{{var_two}}</b> say's {{var_one}}"
}
The variable names and template will be different for every occurrence of the popup.
How can I get this string interpolated with the data that comes with it? I need to pass the pre-built string to a component to be viewed using [innerHTML].
Somewhere after the data was received:
const popupString = popupData.template.replace(
/{{\s?([^{}\s]*)\s?}}/g,
(substring, parsedKey) => {
const replacer = popupData.data[parsedKey];
return typeof replacer !== 'undefined' ? replacer : substring;
}
);
It should equal the <b>world</b> says Hello in your example.
Please note that this code comes from robisim74’s angular-l10n (MIT license).

How to modify a primary key with Restangular?

I've got a very simple object, called "tag" that has only a string primary key. When I go to edit it...
var tag = Restangular.one('tags', 'cat')
.get(function() { // fetches { id: 'cat' } from server
// edit the tag
tag.id = 'dog';
// save changes
tag.post().then(beHappy, beSad);
});
The request that gets sent off is a call to:
POST /tags/cat/dog
with the correct data:
{ id: 'dog' }
I have no doubt that everything work fine if I wasn't trying to modify my primary key, but my server-side REST API isn't expecting the /oldId/newId format, and so I get a 404. Is this a bug in Restangular, or does my REST API need repairing?
Apparently I've been doing CRUD wrong, doing POST for updates and PUT for creates, which is exactly backwards.
Changing it to tag.put() fixed it.

Categories

Resources