I want to execute eval on a string "bean.data.id", but "bean.data" is null. is there any way to make this expression do not throw exception? or what is the right way to handle this? Thanks a lot!
${name?eval}
name = 'bean.data.id'
bean = {"data": null}
You could do this (assuming printing nothing on null is fine):
${'(${name})!'?eval}
Related
I'm trying to replace an empty field with nulls in an UpdateRecord processor.
/title ${field.value:replaceEmpty(null)}
This fails because "null" is not a valid keyword. How does one specify null in the nifi expression language?
You can use the literal() function to return a String value that is the exact input to the function, and you can nest that inside your replaceEmpty method. Try using the expression ${field.value:replaceEmpty(${literal('null')})}.
If you are doing this in the UpdateRecord processor, you want to use Apache NiFi RecordPath syntax, not Expression Language. I believe the CSVReader and others parse even a field value containing only spaces to empty, so a regular expression like replaceRegex( /title, '^(?![\s\S])$', 'null' ) doesn't work.
My suggestion would be to file a Jira requesting this capability. In the mean time, do not use UpdateRecord for this, but rather ReplaceText with a regular expression like ,\s?, for an empty CSV value and replace it with null.
There is a trick using RecordPath, if the field value is blank you can do this to get a null value.
/fieldName[not(isBlank(/fieldName))]
It is giving answer as
{
"fieldname" : "null"
}
here null is a string not a null value.
Bean-shell Post-Processor code:
int totalElements= Integer.parseInt(vars.get("totalElements"));
vars.put("totalElements", String.valueOf(totalElements));
In loop controller, I used these following but couldn't get this value.
${__javaScript(parseInt(${totalElements})};
${__javaScript(parseInt("${totalElements}"))};
${__V(totalElements)};
${totalElements};
Try variable name without semi-colon:
The other issue is if variable totalElements for some reason was not defined, the statement vars.get("totalElements") will return null, and parsing Integer.parseInt(null) will cause an exception, which will cause a failure of the sampler. If that's a desired behavior, fine, but if not, you can do this:
String value = vars.get("totalElements");
int totalElements = (value != null) ? Integer.parseInt(value) : 0;
vars.put("totalElements", String.valueOf(totalElements));
So if variable could not be retrieved, totalElements is set to 0, and thus loop will not run. But sampler will not fail either.
I got the solution of this posted problem. Worked following the below script:
int totalElements= Integer.parseInt(vars.get("totalElements"));
vars.put("totalElements", String.valueOf(totalElements));
Then I have used ${__javaScript("${totalElements}")} in Loop Controller and worked properly.
So I am pushing some elements on my array like this:
upd_city_list << [ j.children[0].text.strip!.gsub(/\s+\W/, ''), j.children[1].text, j.children[1][:href] ]
The above is in an iterator (hence the use of j).
The issue is that from time to time, the j.children[0].text turns up as nil, and Ruby doesn't like that.
I could add a bunch of if statements before this assignment, but that seems a bit inelegant to me.
How do I handle nil cases in this situation in an elegant way?
One possible solution is, when there is a nil value, just push the string none onto the array....but what would that look like?
Thanks.
Edit1:
This is the error I am getting:
NoMethodError: private method ‘gsub’ called for nil:NilClass
The real problem is that strip! returns nil when there are no changes to the string. Your text method is returning a string, it is your strip! method is returning nil. I don't know why it does this. I dislike it, too.
This case of the problem will go away if you just change strip! to strip
In a more general sense, you might create an object to return the array for you. You don't want to go changing (what I assume is) Nokogiri, but you can wrap it in something to hide the train wrecks that result.
You should replace j.children[0].text.strip! with one of two things:
(j.children[0].text || 'none').strip
or
j.children[0].text.to_s.strip
These will, of course, have different effects when the text is nil. I think your ACTUAL problem is that strip! was returning nil, and that should have been obvious to you from the error message.
This might be the case for one to use null object programming pattern. Nil is not a good null object. Try reading here and here. Null object is the elegant way.
nil or a_string will be a_string
so what about (j.children[0].text or 'none')
If you're in rails, this is a great use for the try method.
Also seems that your strip and gsub are redundent. Please consider this implementation:
descriptive_name_1 = j.children[0].text.try(:strip)
descriptive_name_2 = j.children[1].text
descriptive_name_3 = j.children[1][:href]
updated_city_list << [ descriptive_name_1 , descriptive_name_2, descriptive_name_3 ]
w/o try
descriptive_name_1 = j.children[0].text.to_s.strip
descriptive_name_2 = j.children[1].text
descriptive_name_3 = j.children[1][:href]
updated_city_list << [ descriptive_name_1 , descriptive_name_2, descriptive_name_3 ]
If you're in the rails environment you could try try method: https://github.com/rails/rails/blob/82d41c969897cca28bb318f7caf301d520a2fbf3/activesupport/lib/active_support/core_ext/object/try.rb#L50
I have a message (MsgPortConfig):
<NewTable>
<InternalID>1</InternalID>
<InterfaceId>INT079</InterfaceId>
<PortName>PortArchiveNewStartersDestination</PortName>
<Type>FILE</Type>
<Address>file://c:\test\out\archive\destination\NewStarters%MessageID%.txt</Address>
</NewTable>
When I try to access a value via xpath using the following it always returns null.
VarXPath = "/*[local-name()='NewTable']/*[local-name()='Address']/text()";
VarDynamicPortFilePath = xpath(MsgPortConfig, VarXPath);
I don't know how else I can do this, checking the syntax with an application like XPathBuilder works fine but not in BizTalk. what am I missing? thanks.
Use:
VarXPath = "string(/*[local-name()='NewTable' and namespace-uri()='']/*[local-name()='Address' and namespace-uri()=''])";
I'm banging my head against the wall on this one. I was looking at some old database reporting code written in VB6 and came across this line (the code is moving data from a "source" database into a reporting database):
rsTarget!VehYear = Trim(Str(rsSource!VehYear))
When rsSource!VehYear is Null, the above line generates an "Invalid use of Null" run-time error. If I break on the above line and type the following in the Immediate pane:
?rsSource!VehYear
It outputs Null. Fine, that makes sense. Next, I try to reproduce the error:
?Str(rsSource!VehYear)
I get an "Invalid use of Null" error.
However, if I type the following into the Immediate window:
?Str(Null)
I don't get an error. It simply outputs Null.
If I repeat the same experiment with Trim() instead of Str(), everything works fine. ?Trim(rsSource!VehYear) returns Null, as does ?Trim(Null). No run-time errors.
So, my question is, how can Str(rsSource!VehYear) possibly throw an "Invalid use of Null" error when Str(Null) does not, when I know that rsSource!VehYear is equal to Null?
Update: If I type the following in the Immediate window, it works as expected (no error occurs):
?Str(rsSource!VehYear.Value)
This outputs Null. Now, I know that rsSource!VehYear is actually an ADODB.Field instance, but Value is its default property, so Str should be operating on the Value property (which is Null). Even the error message ("Invalid use of Null") suggests that Str is receiving a Null parameter, but how can it treat Null differently in one case and not the other?
My only guess is the internal implementation of Str() is somehow failing to get the default property, and the "Invalid use of Null" error is happening for a different reason (something other than the parameter is causing the "Invalid use of Null", perhaps when it is trying to retrieve the default property from the Field object).
Does anyone have a more detailed, technical explanation for what is actually happening here?
In short:
?Str(rsSource!VehYear)
throws an "Invalid use of Null" error when rsSource!VehYear is Null, but
?Str(rsSource!VehYear.Value)
returns Null.
However, both Trim(rsSource!VehYear) and Trim(rsSource!VehYear.Value) return Null.
If you need a value other than a string, try using IsNull instead:
rsTarget!VehYear = IIf(IsNull(rsSource!VehYear), 0, rsSource!VehYear)
' Note 0 is the default value
The Str function will specifically check if a Null value is passed in and deal with it accordingly. When you pass in an object it attempts to convert the result of a default method to a String. The result of the default method is not passed into the Str method, but Field object is, so a check for the initial Null will fail. The Str function will continue to check the parameter type for datatypes that it supports when it realizes that it has an object, it will attempt to retrieve the default value. It doesn't re-attempt to deal with the default value as it did with the passed in argument, so the attempt to return a Null as a String will fail. It seems MS didn't expect a default value to be Null or any other invalid value for Str. For instance Str doesn't support an empty string either.
This was my workaround in the vb6-days:
rsTarget!VehYear = Trim(Str(rsSource!VehYear & ""))
the & "" will make sure there is allways at least an empty string to work with.
From memory, null database fields are Nothing (or possibly vbNull), which do not have the same rules applied to them as Null. You should just be able to do a quick check:
If (rsSource!VehYear Is Nothing) Then
' Null
Else
' Not null
End If