Parsing a JSON object with Javascript, just won't work - javascript

I'm using this code to get a JSON file stored in the same folder.
var schedtotal = 0;
var requestURL11 = 'schedtotal.json';
var request11 = new XMLHttpRequest();
request11.open('GET', requestURL11);
request11.responseType = 'json';
request11.send();
request11.onload = function() {
window.superHeroes11 = request11.response;
populateHeader11(superHeroes11);
}
function populateHeader11(jsonObj) {
window.schedtotal = jsonObj.total;
console.log("populateHeader function has activated");
console.log(jsonObj);
}
The file looks like this:
{"total": 3}
It's valid JSON. I'm trying to extract the value of total using the same exact method that I've used successfully for all the other JSON parsings in the rest of the file (which I have not included here).
When populateHeader11 is called, it doesn't change schedtotal to equal total. It remains at its original setting of 0. The console log returns from the function as having activated and also returns the JSON file so I know it can access it at least.
I've tried changing .jsonObj.total to .jsonObj['total'] and it didn't change anything.
Previous times I've screwed around with this, it has sometimes returned an error saying it can't get 'total' from null. Now it just doesn't return anything in its current state. What is going on?

You need to parse the JSON string into an object before you try and access the total field.
var jsonString = "{\"total\": 3}";
var jsonObj = JSON.parse(jsonString);
console.log(jsonObj.total);

Related

NiFi how do I pass an attribute to the executeScript processor

The flowfile uses evaluateJsonPath in order to extract values and setup my Attributes. I need to pass some of the attributes into a JavaScript function which I have in a ExecuteScript processor. The setting is for ECMAScript and the JS code is in the Script Body.
So, as an example if my attributes are A, B, C and my function is foo(arg){}
How do I call the function foo(A)?
I have tried putting at the end of the Script Body, after the declaration of my function foo
foo(A);
foo(${A});
But this keeps failing and I am not able to find any examples on how to pass in the value to the function call. I get either a "A is not defined in " or Expects a , and got a {.
What is the proper way to pass an Attribute to the ExecuteScript processor?
UPDATED: SEE BELOW
So as I'm trying to figure this out here is what I'm dealing with.
Read in a JSON file
Set some attributes with EvaluateJSONPath
HERE I NEED TO merge some attributes and want to use the ExecuteScript to run some JavaScript
JAVASCRIPT
var flowFile = session.get();
if(flowFile){
var argFoo = flowFile.getAttribute("someAttribute");
// Set the value as a new Attribute in the flowFile
session.putAttribute(flowFile, "NewAttribute", argFoo);
}
I've also tried things like
var flowFile = session.get();
if(flowFile){
var argFoo = flowFile.getAttribute("someAttribute");
// Create a new flowFile
var newFlowFile = session.create(flowFile);
// Set the value as a new Attribute in the flowFile
session.putAttribute(newFlowFile, "NewAttribute", argFoo);
}
I'm blindly guessing how to get this to work.
Can someone point me in the right direction here on how to use JavaScript within this ExecuteScript processor?
The latest error is "This FlowFile was not created in this session and was not transferred to any Relationship via ProcessSession.transfer()"
Check these sites:
https://nifi.apache.org/docs/nifi-docs/components/org.apache.nifi/nifi-scripting-nar/1.20.0/org.apache.nifi.processors.script.ExecuteScript/additionalDetails.html
https://community.cloudera.com/t5/Community-Articles/ExecuteScript-Cookbook-part-1/ta-p/248922
https://community.cloudera.com/t5/Community-Articles/ExecuteScript-Cookbook-part-2/ta-p/249018
https://community.cloudera.com/t5/Community-Articles/ExecuteScript-Cookbook-part-3/ta-p/249148
https://github.com/mkalika/nifi-executescript-samples
You don't have to create new a FlowFile, if you want only to add a new attribute.
Example
flowFile = session.get();
if (flowFile != null) {
// Get attributes
var greeting = flowFile.getAttribute("greeting");
var message = greeting + ", Script!";
// Set single attribute
flowFile = session.putAttribute(flowFile, "message", message);
// Set multiple attributes
flowFile = session.putAllAttributes(flowFile, {
"attribute.one": "true",
"attribute.two": "2"
});
session.transfer(flowFile, REL_SUCCESS)
}

How to write and read an array of objects to a file

I have this array of objects:
var people = {name:'list 1',mode:0,friends:[{user:1,code:'red'},{user:2,code:'blue'}]};
I want to write it to a file so if the node server crashes I dont lose the data. I did this:
//define variables from file
var file = "../../people.txt";
var open = fs.readFileSync(file);
va data = open.toString();
var name = data.name;
var mode = data.mode;
var friends = data.friends;
whenever a variable changes I save it to a file like this:
function update() {
//dosomething
name = 'new list';
mode = 1;
friends = [{user:4,code:'red'},{user:6,code:'blue'}]
fs.writeFileSync(file,`{name:'${name}',mode:${mode},friends:${friends}'}`,{encoding:'utf8',flag:'w'});
}
This is output onto the file
{name:'list 1',mode:0,friends:[object, object]}
and the data cant be read at all. What am I supposed to do here?
Thank you.
You should convert the JSON data into a string format using JSON.stringify() before writing it to a file, and when reading them out, you should parse the string into JSON using JSON.parse()
More details are here and how to read/write JSON files

How to store data in an array that is stored in a variable?

Following is my problem:
I am testing a system now, that has multiple ID's in every request. There are 2 ID's I want to store in an array and let them run again a response later.
Following is the Body I recieve
{
"id" = 1234;
"Name" = "Meier"
}
So, I store the ID normally with
var body = JSON.parse(responseBody);
postman.setEnvironmentVariable("ID", body.id);
with that I can store 1 ID in the variable, but can't put a second one in it. For that I would have to duplicate the request, set a second variable, change code everytime the needed cases are changed.
What I want to know now is: How can I store multiple ID's in a Environment Variable to compare them with a response at the end of the collection?
I'm not entirely familiar with postman, but if I'm understanding correctly and you want to store up the Id's from the response then you could use something like -
var body = JSON.parse(responseBody);
var storedIds = postman.getEnvironmentVariable("ID");
if(storedIds) {
storedIds.push(body.id)
} else {
storedIds = [body.id]
}
postman.setEnvironmentVariable("ID", storedIds);
Edit
From my own googling, it appears you cannot store arrays in environment variables in postman. Therefore you could try doing something like this -
var body = JSON.parse(responseBody);
var storedIds = postman.getEnvironmentVariable("ID");
if (storedIds) {
storedIds = storedIds.concat(',' + body.id)
} else {
storedIds = body.id
}
postman.setEnvironmentVariable("ID", storedIds);
Then when you want to read it back out to loop over it or whatever you want to do you can use
var idsArray = postman.getEnvironmentVariable("ID").split(',')
which will split the string up to give you an array.

How to get to request parameters in Postman?

I'm writing tests for Postman which in general works pretty easily. However, I now want to access some of the data of the request, a query parameter to be exact.
You can access the request URL through the "request.url" object which returns a String. Is there an easy way in Postman to parse this URL string to access the query parameter(s)?
The pm.request.url.query.all() array holds all query params as objects.
To get the parameters as a dictionary you can use:
var query = {};
pm.request.url.query.all().forEach((param) => { query[param.key] = param.value});
I have been looking to access the request params for writing tests (in POSTMAN). I ended up parsing the request.url which is available in POSTMAN.
const paramsString = request.url.split('?')[1];
const eachParamArray = paramsString.split('&');
let params = {};
eachParamArray.forEach((param) => {
const key = param.split('=')[0];
const value = param.split('=')[1];
Object.assign(params, {[key]: value});
});
console.log(params); // this is object with request params as key value pairs
edit: Added Github Gist
If you want to extract the query string in URL encoded format without parsing it. Here is how to do it:
pm.request.url.getQueryString() // example output: foo=1&bar=2&baz=3
pm.request.url.query returns PropertyList of QueryParam objects. You can get one parameter pm.request.url.query.get() or all pm.request.url.query.all() for example. See PropertyList methods.
It's pretty simple - to access YOUR_PARAM value use
pm.request.url.query.toObject().YOUR_PARAM
Below one for postman 8.7 & up
var ref = pm.request.url.query.get('your-param-name');
I don't think there's any out of box property available in Postman request object for query parameter(s).
Currently four properties are associated with 'Request' object:
data {object} - this is a dictionary of form data for the request. (request.data[“key”]==”value”) headers {object} - this is a dictionary of headers for the request (request.headers[“key”]==”value”) method {string} - GET/POST/PUT etc.
url {string} - the url for the request.
Source: https://www.getpostman.com/docs/sandbox
Bit late to the party here, but I've been using the following to get an array of url query params, looping over them and building a key/value pair with those that are
// the message is made up of the order/filter etc params
// params need to be put into alphabetical order
var current_message = '';
var query_params = postman.__execution.request.url.query;
var struct_params = {};
// make a simple struct of key/value pairs
query_params.each(function(param){
// check if the key is not disabled
if( !param.disabled ) {
struct_params[ param.key ] = param.value;
}
});
so if my url is example.com then the array is empty and the structure has nothing, {}
if the url is example.com?foo=bar then the array contains
{
description: {},
disabled:false
key:"foo"
value:"bar"
}
and my structure ends up being { foo: 'bar' }
Toggling the checkbox next to the property updates the disabled property:
have a look in the console doing :
console.log(request);
it'll show you all you can get from request. Then you shall access the different parameters using request., ie. request.name if you want the test name.
If you want a particular element in the url, I'm afraid you'll have to use some coding to obtain it (sorry I'm a beginner in javascript)
Hope this helps
Alexandre
Older post, but I've gotten this to work:
For some reason the debugger sees pm.request.url.query as an array with the items you want, but as soon as you try to get an item from it, its always null. I.e. pm.request.url.query[0] (or .get(0)) will return null, despite the debugger showing it has something at 0.
I have no idea why, but for some reason, it is not at index 0, despite the debugger claiming it is. Instead, you need to filter the query first. Such as this:
var getParamFromQuery = function (key)
{
var x = pm.request.url.query;
var newArr = x.filter(function(item){
return item != null && item.key == key;
});
return newArr[0];
};
var getValueFromQuery = function (key)
{
return getParamFromQuery(key).value;
};
var paxid = getValueFromQuery("paxid");
getParamFromQuery returns the parameter with the fields for key, value and disabled. getValueFromQuery returns just the value.

How to get a random value from a Fixture Data in Ember

I'm playing with a sample Ember app that shows all the data stored in a Fixture, and finally tries to show a random data from the fixture.
Complete Demo here: http://jsbin.com/ifatot/2/edit
Everything works fine, however, I'm not able to get a random index out of the Ember Data. I'm trying to find its length and grab the random index but I believe the length is always coming up as 0, even though I have data in there.
The function looks like this:
App.ThoughtsController = Ember.ArrayController.extend({
randomMessage: function() {
var thoughts = this.get('model');
var len = thoughts.get('length');
var randomThought = (Math.floor(Math.random()*len));
return thoughts.objectAt(randomThought);
}.property('model')
});
You should add the length property as another dependent on the randomMessage computed property. This will allow the content to have finished resolving and have a length.
randomMessage: function() {
var len = this.get('length');
var randomThought = (Math.floor(Math.random()*len));
return this.objectAt(randomThought);
}.property('model', 'length')
Here's an updated jsbin.

Categories

Resources