Transformation on POST with a url encoded JSON payload - javascript

Okay, I'm not getting this one right off so we'll see if I'm missing the obvious.
Given the request
curl "https://api.me.com/v1/visitors" --data "visitor=%7B%0A++%22funnels%22%3A+%7B%7D%2C%0A++%22_partition%22%3A+96%2C%0A++%22metric_sets%22%3A+%7B%0A++++%2234%22%3A+%7B%0A++++++%22safari%22%3A+1%0A++++%7D%0A++%7D%2C%0A++%22flags%22%3A+%7B%0A++++%22Book+Pack+Purchaser%22%3A+false%2C%0A++++%22Boat+PP+Viewer%22%3A+true%2C%0A++++%22Boat+Purchaser%22%3A+false%2C%0A++++%22Mobile+Shopper%22%3A+true%2C%0A++++%22Visitor+Buy%22%3A+false%2C%0A++++%22Testing%22%3A+true%2C%0A++++%22Book+Pack+PP+Viewer%22%3A+false%2C%0A++++%22Women%27s+Dept+Visitors%22%3A+true%2C%0A++++%22Boat+Abandoner%22%3A+false%0A++%7D%2C%0A++%22replaces%22%3A+%5B%5D%2C%0A++%22shard_token%22%3A+21000096%0A%7D"
You'll notice that the --data passed is a JSON object that has been encoded.
{"not":"my design"}
You could go here to encode it: http://www.url-encode-decode.com/ basically it turns into:
{
"funnels": {},
"_partition": 96,
"metric_sets": {
"34": {
"safari": 1
}
},
"flags": {
"Book Purchaser": false,
"Boat PP Viewer": true,
"Boat Purchaser": false,
"Mobile Shopper": true,
"Visitor Buy": false,
"Testing": true,
"Book Pack PP Viewer": false,
"Women's Dept Visitors": true,
"Boat Abandoner": false
},
"replaces": [],
"shard_token": 21000096
}
Well I can't figure out how to get the value into a JSON object in a Script so I can start mashing up the data. I got a...
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Javascript async="false" continueOnError="false" enabled="true" timeLimit="200" name="Script-ProcessRequestVars">
<DisplayName>Script-ProcessRequestVars</DisplayName>
<FaultRules/>
<Properties/>
<ResourceURL>jsc://Script-ProcessRequestVars.js</ResourceURL>
</Javascript>
With a...
var processRequestPayload = function(){
context.setVariable("my.requestVerb",context.proxyRequest.method);
context.setVariable("my.visitor",context.proxyRequest.body.asForm['visitor'][0]);
var visitObj = JSON.parse(context.proxyRequest.body.asForm['visitor'][0]);
var shard = visitObj.shard_token;
};
function init() {
processRequestPayload();
}
init();
But all I get is a...
{
"fault": {
"faultstring": "Execution of Script-ProcessRequestVars failed on line 4 with error: 1",
"detail": {
"errorcode": "steps.javascript.ScriptExecutionFailedLineNumber"
}
}
}
What am I missing??

Kris, try replacing:
context.setVariable("my.visitor", context.proxyRequest.body.asForm['visitor'][0]);
With
context.setVariable("my.visitor", request.body.asForm['visitor'][0]);
There seems to be an issue with context.proxyRequest.body. If this issue gets fixed with above workaround, please open a ticket and in the meantime use this workaround.

I'm not sure why you're passing your JSON as a form parameter... Personally I would send the body as Content-Type: application/json and use the JSON Path in an ExtractVariables policy to set Apigee variables for the JSON you want to manipulate:
POST
Content-type: application/json
{
"funnels": {},
"_partition": 96,
"metric_sets": {
"34": {
"safari": 1
}
},
"flags": {
"Book Purchaser": false,
"Boat PP Viewer": true,
"Boat Purchaser": false,
"Mobile Shopper": true,
"Visitor Buy": false,
"Testing": true,
"Book Pack PP Viewer": false,
"Women's Dept Visitors": true,
"Boat Abandoner": false
},
"replaces": [],
"shard_token": 21000096
}
ExtractVariables example:
<ExtractVariables async="false" continueOnError="false" enabled="true" name="Extract-Variables-1">
<DisplayName>Extract Variables 1</DisplayName>
<FaultRules/>
<JSONPayload>
<Variable name="name">
<JSONPath>$.flags.Book%20Purchaser</JSONPath>
</Variable>
</JSONPayload>
<Source clearPayload="false">request</Source>
<VariablePrefix>apigee</VariablePrefix>
</ExtractVariables>
BTW -- you might also want to avoid putting spaces in your JSON labels -- not really standard and can cause parsing problems...
ExtractVariables http://apigee.com/docs/api-services/content/extract-message-content-using-extractvariables

Related

How to call FullTextSearchKnowledgeArticle action using REST calls?

How can we call MSCRM action using some HTTP Client request (c#)?
Can any one please assist on this.
The documentation is not covering this action, and I was able to pull this payload from couple of references. But I could not test this in my environment, please test it yourself.
The sample will look like this:
{
"SearchText": "",
"UseInflection": false,
"RemoveDuplicates": false,
"StateCode": 3,
"QueryExpression": {
"#odata.type": "Microsoft.Dynamics.CRM.QueryExpression",
"EntityName": "knowledgearticle",
"ColumnSet": {
"AllColumns": true
},
"Distinct": false,
"NoLock": false,
"PageInfo": {
"PageNumber": 1,
"Count": 10,
"ReturnTotalRecordCount": true,
"PagingCookie": ""
},
"LinkEntities": [],
"Criteria": {
"FilterOperator": "And",
"Conditions": [
{
"EntityName": "knowledgearticle",
"AttributeName": "languagelocaleid",
"Operator": "Equal",
"Values": [
"56940B3E-300F-4070-A559-5A6A4D11A8A3"
]
}
]
}
}
}
Reference.
Make a POST request to the the following URL.
[Your organization root URL]/api/data/v9.1/FullTextSearchKnowledgeArticle
Here is one sample payload that works. You can optionally add additional filters to filter the search result.
{
"SearchText":"test",
"UseInflection":true,
"RemoveDuplicates":true,
"StateCode":3,
"QueryExpression":{
"#odata.type":"Microsoft.Dynamics.CRM.QueryExpression",
"EntityName":"knowledgearticle",
"ColumnSet":{
"AllColumns":true
},
"PageInfo":{
"PageNumber":1,
"Count":10
},
"Orders":[
{
"AttributeName":"modifiedon",
"OrderType":"Descending"
}
]
}
}
Refer the link below for sample code for connecting to Dynamics.
CDSWebApiService class library (C#)

'clickSelector' and 'hoverSelector' attributes are not working for backstopJS

I am using Backstopjs with chrome engine. I am able to take screenshot by passing different urls's and using various attributes but when I am trying to click a button before taking screenshots, the click is not working.
The attributes 'clickSelector' and 'hoverSelector' are getting ignored and no action is getting performed.
Please let me know how to use these attributes.
Below is my backstop.json file where i am opening google.com and trying to click on 'I am feeling lucky' before taking screenshot :
``
{
"id": "backstop_default",
"viewports": [
{
"label": "iPad",
"width": 1024,
"height": 768
}
],
"onBeforeScript": "chromy/onBefore.js",
"onReadyScript": "chromy/onReady.js",
"scenarios": [
{
"label": "Google",
"url": "https://www.google.co.in",
"referenceUrl": "https://www.google.co.in",
"readyEvent": "",
"readySelector": "",
"delay": 0,
"hideSelectors": [],
"clickSelector": "input[name='btnI']",
"hoverSelector": "input[name='btnI']",
"removeSelectors": [],
"postInteractionWait": "",
"selectors": ["viewport"],
"selectorExpansion": true,
"misMatchThreshold" : 0.1,
"requireSameDimensions": true
}
],
"paths": {
"bitmaps_reference": "backstop_data/bitmaps_reference",
"bitmaps_test": "backstop_data/bitmaps_test",
"engine_scripts": "backstop_data/engine_scripts",
"html_report": "backstop_data/html_report",
"ci_report": "backstop_data/ci_report"
},
"report": ["browser"],
"engine": "chrome",
"engineFlags": [],
"engineOptions": {
"waitTimeout": 120000,
"chromePath": "C:/Program Files (x86)/Google/Chrome/Application/chrome.exe",
"chromeFlags": "['--disable-gpu', '--force-device-scale-factor=1']"
},
"asyncCaptureLimit": 2,
"asyncCompareLimit": 50,
"debug": false,
"debugWindow": true
}
``
Trying setting "postInteractionWait" to an integer. This indicates how long to wait after BackstopJS clicks or hovers.

How to access variable from Ajax FormData.append?

I am sending an uploaded file from my HTML form to my server and am trying to add a custom attribute to FormData(), but it's not showing up on my server side.
I add my custom attribute by doing var formData = new FormData();, then appending by doing formData.append("airlinename",airline_name);, but once I get the data on the Server side, I look in the req object and can't find airlinename. How do I access my custom attribute?
I am able to access the file just fine, but I can't find how to access the custom attribute I appended to formData.
HTML Form
<form role="form">
<input type="text" id="load_db_name" name="load_db_name">
<input type="file" id="load_db_dir" name="load_db_dir">
</form>
<button id="load_generateDiagram" onClick="loadPastDiagram();" type="button">Load</button>
Client JS
function loadPastDiagram()
{
var db_dir = document.getElementById('load_db_dir').files[0] || null;
var _files = [db_dir];
var airline_name = document.getElementById('load_db_name').value.trim();
loadDiagram(airline_name,_files);
}
function loadDiagram(airline_name, files)
{
var formData = new FormData();
for (var f in files) {
formData.append("files", files[f]);
}
formData.append("airlinename",airline_name); //<--- can't find this on the server side
$.ajax({
url: '/loadDiagram',
type: 'POST',
success: function(res) {
console.log("Success");
},
error: function(err) {
console.log("Error ",err);
},
data: formData,
//Options to tell jQuery not to process data or worry about content-type.
cache: false,
contentType: false,
processData: false
});
}
Server JS
app.post('/loadDiagram', function(req,res){
console.log("[FILES]" + JSON.stringify(req.airlinename));
console.log("[FILES]" + JSON.stringify(req.files.airlinename));
console.log("[FILES]" + JSON.stringify(req.files.files));
});
Output
[DEV] [FILES]undefined
[DEV] [FILES]undefined
[DEV] [FILES]{
"fieldName": "files",
"originalFilename": "Tool_fresshhh.tar.gz",
"path": "../Output-Files/2833-fwh0ql.tf9od2t9.gz",
"headers": {
"content-disposition": "form-data; name=\"files\"; filename=\"Tool_fresshhh.tar.gz\"",
"content-type": "application/x-gzip"
},
"ws": {
"_writableState": {
"objectMode": false,
"highWaterMark": 16384,
"needDrain": true,
"ending": true,
"ended": true,
"finished": true,
"decodeStrings": true,
"defaultEncoding": "utf8",
"length": 0,
"writing": false,
"corked": 0,
"sync": false,
"bufferProcessing": false,
"writecb": null,
"writelen": 0,
"bufferedRequest": null,
"lastBufferedRequest": null,
"pendingcb": 0,
"prefinished": true,
"errorEmitted": false,
"bufferedRequestCount": 0,
"corkedRequestsFree": {
"next": {
"next": null,
"entry": null
},
"entry": null
}
},
"writable": false,
"domain": null,
"_events": {
"error": [null],
"close": [null]
},
"_eventsCount": 2,
"path": "../Output-Files/2833-fwh0ql.tf9od2t9.gz",
"fd": null,
"flags": "w",
"mode": 438,
"autoClose": true,
"bytesWritten": 449781,
"closed": true
},
"size": 449781,
"name": "Tool_fresshhh.tar.gz",
"type": "application/x-gzip"
}
Versions
jQuery v1.11.1
Express Version: 3.14.0
Node Version: v6.5.0
I know this is "uncool"...
But I saw this question as it was posted, more than 1 hour ago, and saw (quite fast!!) the solution posted as a comment.
I waited on him or her to post it, so I could learn something.
But since Jaromanda X was actually last seen 5 minutes ago without posting the answer...
I guess he or she is not really interested about rep. points!
So just to mark this question as answered...
;)
Server JS
app.post('/loadDiagram', function(req,res){
console.log("[FILES]" + JSON.stringify(req.body.airlinename)); // <--
console.log("[FILES]" + JSON.stringify(req.files.files));
});
«First one to post it, gets it! »

Is ConsistentRead param of DynamoDb scan really supported in JS AWS SDK?

When I invoke scan with ConsistentRead param I receive
"Unexpected key 'ConsistentRead' found in params","name":"UnexpectedParameter","stack":"UnexpectedParameter: Unexpected key 'ConsistentRead' found in params
As I can see there is no ConsistentRead param in dynamodb-2012-08-10.min.json
"Scan": {
"input": {
"type": "structure",
"required": [
"TableName"
],
"members": {
"TableName": {},
"AttributesToGet": {
"shape": "Sj"
},
"Limit": {
"type": "integer"
},
"Select": {},
"ScanFilter": {
"shape": "S30"
},
"ConditionalOperator": {},
"ExclusiveStartKey": {
"shape": "S6"
},
"ReturnConsumedCapacity": {},
"TotalSegments": {
"type": "integer"
},
"Segment": {
"type": "integer"
},
"ProjectionExpression": {},
"FilterExpression": {},
"ExpressionAttributeNames": {
"shape": "Sm"
},
"ExpressionAttributeValues": {
"shape": "S2g"
}
}
},
I just found that in Release: AWS SDK for JavaScript v2.1.39
AWS.DynamoDB API Update
Submitted By: Aditya#AWS
Created On: July 14, 2015 7:36 PM GMT
Last Updated: July 14, 2015 7:36 PM GMT
Updated AWS.DynamoDB API to add support for the ConsistentRead parameter with the Scan API operation.
So I need to update aws-sdk
This exceptions seems to occur for me as well with the python boto3 package. Although boto3 documentation indicates that the boolean parameter "ConsistentRead" may be added to the scan() method, when I add this parameter to my request using the client, I receive the following exception:
botocore.exceptions.ParamValidationError: Parameter validation failed:
Unknown parameter in input: "ConsistentRead", must be one of: TableName, IndexName,
AttributesToGet, Limit, Select, ScanFilter, ConditionalOperator, ExclusiveStartKey,
ReturnConsumedCapacity, TotalSegments, Segment, ProjectionExpression, FilterExpression,
ExpressionAttributeNames, ExpressionAttributeValues
Since AWS documentation indicates that you can include a ConsistentRead parameter, I'm not sure whether this is a problem for me, the dynamodb local build that I have been using for testing, boto3 or the AWS api itself. Has anyone else gotten this parameter to work?

Knockout.js mapping ignore

We're working with knockout.js and knockout.mapping.js on .NET MVC 4. Let's say I have such JSON:
{
"deliveryPointType": "0",
"deliveryPointTypes": [
{
"id": 0,
"text": "Pridėti rankiniu būdu"
},
{
"id": 1,
"text": "Siųsti visiems regiono objektams"
}
],
"showRegionSelection": false,
"showDeliveryPointSelection": true,
"regionId": "",
"userHasRegions": "False",
"propertyNames": {
"deliveryPointTypeName": "Pridėti rankiniu būdu"
},
"initialMaterials": [
{
"quantity": 0,
"materialTypeId": "",
"propertyNames": {},
"validMaterial": true,
"showMaterialError": false,
"materialTypeAjax": {
"quietMillis": 300,
"cache": false,
"dataType": "json",
"type": "GET",
"url": "/lt-LT/Material/MaterialTypeNameLookup"
}
}
],
"deliveryBuildings": [
{
"clientId": "1",
"buildingId": "1",
"regionId": "",
"newBuilding": false,
"validClient": true,
"validBuilding": true,
"validRegion": true,
"showClientError": false,
"showBuildingError": false,
"showRegionError": false,
"propertyNames": {
"clientName": "klientas",
"buildingName": "ASD project, Antagynės gatvė, Kaunas, Lietuvos Respublika"
},
"clientAjax": {
"quietMillis": 300,
"cache": false,
"dataType": "json",
"type": "GET",
"url": "/lt-LT/Task/PayerLookup"
},
"buildingAjax": {
"quietMillis": 300,
"cache": false,
"dataType": "json",
"type": "GET",
"url": "/lt-LT/Object/GetClientAddressListByQuery"
},
"regionAjax": {
"quietMillis": 300,
"cache": false,
"dataType": "json",
"type": "GET",
"url": "/lt-LT/Object/RegionNameLookup"
}
}
],
"hasNewBuildings": false,
"showBuildingValidation": false,
"showMinimumBuildingRequiredValidation": false,
"showMaterialValidation": false,
"validRegion": true,
"showRegionError": false,
"regionAjax": {
"quietMillis": 300,
"cache": false,
"dataType": "json",
"type": "GET",
"url": "/lt-LT/Object/RegionNameLookup"
}
}
On form submit fail (if something goes wrong/invalid in service) it is repopulated with previous values. We convert ViewModel to JSON on form submit with $('#BuildingsJSON').val(ko.mapping.toJSON(viewModel.deliveryBuildings)).
On form repopulating, we parse JSON with ko.mapping.fromJSON(deliveryBuildings, mapping, viewModel.deliveryBuildings)(); mapping is just an empty object for now (tried "ignore" with no luck).
We use select2 fields to select addresses of buildings from a list (using ajax). Thing is, fromJSON populates almost every json property as observable, which I don't need. On select2 open we get an exception:
Uncaught TypeError: Object function observable() {
if (arguments.length > 0) {
// Write
// Ignore writes if the value hasn't changed
if (!observable['equalityComparer'] || !observable['equalityComparer'](_latestValue, arguments[0])) {
observable.valueWillMutate();
_latestValue = arguments[0];
if (DEBUG) observable._latestValue = _latestValue;
observable.valueHasMutated();
}
return this; // Permits chained assignments
}
else {
// Read
ko.dependencyDetection.registerDependency(observable); // The caller only needs to be notified of changes if they did a "read"
operation
return _latestValue;
}
} has no method 'toUpperCase'
I've debugged where it breaks - on type property of ajax call. I figured that we need to exclude ajax properties from casting to observable.
So, the question is: how can one not cast specific properties of specific objects to observable()? Is it enough using mapping plugin, is additional plugin needed or is it even impossible?
Have you looked at using the copy keyword in your mapping binding? This just copies the value over into a js property rather than making it an observable.
From the documentation:
var mapping = {
'copy': ["propertyToCopy"]
}
ko.mapping.fromJS(data, mapping, viewModel);

Categories