NiFi how do I pass an attribute to the executeScript processor - javascript

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

Related

Variable used to store data from Excel file broken? JavaScript

I am currently developing a Keyword driven framework using JavaScript / TestComplete and have an Excel file which contains a step number, Description, Keyword, Locator and Data.
I am currently reading the data from the Excel file (.xlsx) and storing the data (in this case the locator) in a variable..
I am storing the String Browsers.Item(btlExplorer,"",Browsers.pX64 in a variable called locator. When I then attempt this: locator.Run(https://www.google.ie/?gws_rd=ssl#spf=1); I receive this error: JavaScript runtime error. TypeError. getLocator(...).Run is not a function.
This is my getLocator function:
function getLocator(x){
var driver;
var value;
driver = DDT.ExcelDriver("C:\\Users\\Username\\Desktop\\Automation Framework.xlsx", "Sheet1", false);
while (! driver.EOF() && driver.Value(0) != x){
DDT.CurrentDriver.Next();
}
value = driver.Value(3);
Log.Message(value);
DDT.CloseDriver(driver.Name);
return value;
}
And here is the function I am running:
function openGoogle()
{
//Launches the specified browser and opens the specified URL in it.
getLocator(1).Run("https://www.google.ie/?gws_rd=ssl#spf=1");
}
I am new to JavaScript, if you could give me any tips / advice on what is going wrong it would be greatly appreciated.
Since the value returned by the getLocator function is a string, you can work with it as a string and it does not have the Run method.
To get the actual object with the Run method, you need to evaluate the string in this way:
function openGoogle()
{
//Launches the specified browser and opens the specified URL in it.
let brwsr = eval(getLocator(1));
brwsr.Run("https://www.google.ie/?gws_rd=ssl#spf=1");
}

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

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

I can't change dom from dom element stored as an attribute

I Apologize if there is already an answer, I found nothing usefull.
I am developing a little JS code with some blocks that need to change their html code.
So I have a main object with 2 kinds of attributes :
custom objects with a getHtml() method
dom elements that are initialized with a id tag then should be changed.
My first version worked : i set some javascript event and methods, then my block content was changed.
Of course (!) I needed to modify the code to implements new features and now my method return html code but .innerHTML on my variables does not work anymore.
Let me show you some code and explain it
var AtelierScreen = function(ancre, dataJson){
if(!ancre.charAt) throw "Invalid string-dealer name type ('"+ancre+"') should be String";
if(ancre.length==0) throw "Invalid string-dealer name ('"+ancre+"') cannot be empty";
this.atelierContent;
this.operationMenu;
this.operationMenuContent;
this.operationRecap;
this.operationRecapContent;
this.create=function(obj,tagsuffix){
var tag = ancre+tagsuffix;
this.atelierContent.innerHTML += "<div id='"+tag+"'></div>";
var content = document.getElementById(tag);
if(!content) throw "Invalid html anchor using '"+tag+"' as an html id";
content.innerHTML=obj.getHtml();
return content;
}
try{
var dataObject = JSON.parse(dataJson);
this.atelierContent = document.getElementById(ancre);
if(!this.atelierContent) throw "Invalid html anchor using '"+ancre+"' as an html id";
// MENU
this.operationMenu = new OperationMenu(dataObject["dealer"],dataObject["operations"]);
this.operationMenuContent=this.create(this.operationMenu,"_menu");
this.operationMenuContent.innerHTML+="after init";
// RECAP
this.operationRecap = new OperationRecap();
this.operationRecapContent=this.create(this.operationRecap,"_recap");
this.operationMenuContent.innerHTML+="after recap init";
} catch(error){
throw "Error decoding json data :\n'"+error+"'\n\nJson =\n'"+dataJson+"'";
}
this.setSelectedModel=function(model){
this.operationMenuContent.innerHTML+="setSelectedModel";
var isTheSame = this.operationMenu.setSelectedModel(model);
if(!isTheSame) this.clearOperationItemFromRecap();
var temp = this.operationMenu.getHtml()
this.operationMenuContent.innerHTML=temp;
}
}
Quick overview
all my attributes and a method to help initializing them.
a try catch to check the json data.
I initialize my attributes with the method
some methods to interact with the program
Here is what happen
Json in parsed correctly
My 1st block is created, return its html code that is put in the 1st content attribute. I add some text again into the dom as a test (it works)
My 2nd block is created, return its html code that is put in the 2nd content attribute. I add some text again in the 1st content attribute as a test. It fail at this point.
my methods does not help in any way. My content attribute does not seem to respond.
I can still get the content attribute value
atelierScreen.operationMenuContent.innerHTML;
But I cannot insert text in dom.
atelierScreen.operationMenuContent.innerHTML="";
does nothing.
Do I need to query the dom with document.getElement ... EACH TIME ?
My previous version with dom elements as attributes was working...
I am missing something, this is so frustrating ;)
Please help.
Thanks
After some research, it could be because of using innerHTML.
It looks like using innerHTML destroy the child elements.
I need to work on this first but I will try something like :
create Block "abstract" parent class with tag and content parameter, constructor with tag
prototype getContent() will look like :
if(content==null) content = document.getElementById(this.tag);
return content;
initialize my main "screen" object with an array of my objects
loop on array to get tag and initialize innerHTML
loop on array to instantiate objects
getContent will handle the rest.
I will give you some feedback
Ok, this is what i did
var AtelierScreen = function(ancre, dataJson){
try{
var dataObject = JSON.parse(dataJson);
this.atelierContent = document.getElementById(ancre);
if(!this.atelierContent) throw "Invalid html anchor using '"+ancre+"' as an html id";
var blocks = [
this.operationMenu = new OperationMenu(...),
this.operationRecap = new OperationRecap(...),
this.operationResult = new OperationResult(...)
];
for (var i = 0; i < blocks.length; i++) {
var block=blocks[i];
this.atelierContent.innerHTML += "<div id='"+block.tag+"'></id>";
}
for (var i = 0; i < blocks.length; i++) {
var block=blocks[i];
block.getContent().innerHTML = block.getHtml();
}
} catch(error){
throw "Error decoding json data :\n'"+error+"'\n\nJson =\n'"+dataJson+"'";
}
}
I parse Json parameter inside try/catch
I create the screen element, that will be used to initialize my anchors
I create my array of blocks and initialize my objects in the same time (i wasn't sure it would work, if those attributes would be found later, but it does). Onjects contains their anchors and content parameter.
1st loop to add blocks anchors
2nd loop to create html content

Accessing FancyTree Node Data in JavaScript

I'm using FancyTree for the first time, and I would like define some custom node data, specifically an attribute named "content" in the HTML data used to create the tree:
<li id="xxxx" data-content="true" class="folder">
I have an init event-handler written in JavaScript and I want to access my custom data attribute there:
init: function(event, data, flag)
{
var tree = $("#tree").fancytree("getTree");
node = tree.getNodeByKey(key);
var data = node.data;
In an online tutorial, I saw that my custom attribute would be accessible as node.data.content, but I'm unable to display my custom attribute in an alert box to demonstrate that it was actually defined. How do I access my custom data attribute in my JavaScript function?
Sheldon
Ok, so i finally got it working. Your were close to getting your result.
The key variable is a string which represent the 'id' attribute of each LI element in your tree. You will obtain the node with that key. Once the node is obtained, you can retrieve your custom data attribute associated to that node. Since our 'data' variable is an object, containing key/value, you need to call it's 'key' name on the data object to retrieve the value, like so 'data.content'.
JS
$(function () {
// using default options
//Caching DOM element
var $myTree = $("#tree").fancytree();
// Get the DynaTree object instance
var tree = $myTree.fancytree("getTree");
//Set my key
var key = "id1";
//Get the node
var node = tree.getNodeByKey(key);
//Get the custom data attribute associated to that node
var data = node.data;
//data is an object so, data.content will give you the value of the attribute
alert(data.content);
});
JSFIDDLE
Hope this helps!

Looking for general feedback on a URL-parsing script of mine (Javascript)

I'm fairly new to Javascript, and assembled the following (part is from an example online, rest is by me):
This works reliably, I'm just wondering how many best-practices I'm violating. If someone is nice enough to provide general feedback about the latter part of this script, that would be appreciated.
The two included functions are to (1) capture the incoming website visitor's referral data on a page, including URL query strings for analytics, and store it to a cookie. (2) When the visitor completes a form, the script will read the cookie's URL value, parse this URL into segments, and write the segment data to pre-existing hidden inputs on a form.
Example URL this would capture and parse: http://example.com/page?utm_source=google&utm_medium=abc&utm_campaign=name1&utm_adgroup=name2&utm_kw=example1&kw=example2&mt=a&mkwid=xyz&pcrid=1234
function storeRef() { //this function stores document.referrer to a cookie if the cookie is not already present
var isnew = readCookie('cookiename'); //set var via read-cookie function's output
if (isnew == null) {
var loc=document.referrer;
createCookie('cookiename',loc,0,'example.com'); //create cookie via function with name, value, days, domain
}
}
function printQuery() { //function to parse cookie value into segments
var ref=readCookie('cookiename'); //write cookie value to variable
var refElement = ref.split(/[?&]/); //create array with variable data, separated by & or ?. This is for domain info primarily.
var queryString = {}; //From http://stevenbenner.com/2010/03/javascript-regex-trick-parse-a-query-string-into-an-object/
ref.replace(
new RegExp("([^?=&]+)(=([^&]*))?", "g"),
function($0, $1, $2, $3) { queryString[$1] = $3; }
);
//write segments to form field names below.
document.getElementsByName('example1')[0].value = refElement[0]; //exampleX is a form hidden input's name. I can not use getElementById here.
//need to be able to manually define these, which is why they aren't in a loop, though I'm not sure how to loop an array referenced in this way
document.getElementsByName('example2')[0].value = queryString['utm_source'];
document.getElementsByName('example3')[0].value = queryString['utm_medium'];
document.getElementsByName('example4')[0].value = queryString['utm_term'];
document.getElementsByName('example5')[0].value = queryString['utm_content'];
document.getElementsByName('example6')[0].value = queryString['utm_campaign'];
document.getElementsByName('example7')[0].value = queryString['utm_adgroup'];
document.getElementsByName('example8')[0].value = queryString['utm_kw'];
document.getElementsByName('example9')[0].value = queryString['kw'];
document.getElementsByName('example10')[0].value = queryString['mt'];
document.getElementsByName('example11')[0].value = queryString['mkwid'];
document.getElementsByName('example12')[0].value = queryString['pcrid'];
}
Thank you!
why would you need to use a cookie to store the data for that, if unless you wanna keep track of the visitors visiting to your site?

Categories

Resources