Currently, I am attempting to write a conditional statement that states the following
If($JSON.response = false){
'Dont do anything and continue to the next block of code.'
}
Right now the JSON returns like this when there is no data:
response_code response
------------- --------
0 {}
This is what I have so far:
If($json.response = 0){
'Dont do anything here'
}elseif($json.response = 1){
'Do the code'
}
I'd like to add that response_code is always equal to 0 when the response is error free as in status code 200. However, when there are no fields returned response is just an empty hashtable.
Do you really want to be testing json.response rather than json.response_code? The numeric comparison suggests that you should be testing json.response_code.
Also, if json is a structure that is stored in a variable, you should be testing it as $json.response_code - note the $ - and using the -eq comparison operator as #JamesC. noted.
Finally, unless you're likely in the future to change what you do in the event that $json.response_code is zero, just drop that test entirely, and only test for $json.response_code values where you actually do something.
I found the answer since the object is an array it was best to roll out like this.
If($json.object.Count -eq 0){
'dont do the code'
}Else{
'Do the code'}
Related
I'm trying to create a loop to read, for example, 4200 users from 1000 to 1000 but I can't get it to cut when it reaches the end. I tried it with if, for and I couldn't do it.
I have programmed in JAVA but with Groovy I see that the structure is different.
urlUsers = urlUsers.concat("/1/1000");
List<UserConnectorObject> usersList = null;
while({
gesdenResponse = GesdenUtils.sendHttpRequest(urlUsers, "LOOKUP", null,
request.getMetaData()?.getLogin(), request.getMetaData()?.getPassword());
log.info("Users data in JSON: "+gesdenResponse.getOutput())
usersList = GesdenUtils.fromJSON(gesdenResponse.getOutput(), GesdenConstants.USER_IDENTITY_KEY);
usersList.size() == 10;
log.info("List size in JSON "+usersList.size());
}()) continue
Groovy has lots of loop structures, but it is crucial to separate the regular ones (lang built-ins) and the api functions which take closure as an argument
take closure - no plain way to escape
If you want to iterate from A to B users, you can use, for instance,
(10..20).each { userNo -> // Here you will have all 10 iterations
if ( userNo == 5) {
return
}
}
If something outrageous happens in the loop body and you cannot use return to escape, as loop boddy is a closure (separate function) and this resurn just exits this closure. Next iteration will happen just after.
use regular lang built-in loop structures - make use of break/continue
for (int userNo in 1..10) { // Here you will have only 5 iterations
if (userNo == 5) {
break
}
}
It looks like your closure always return falsy because there is no explicit return, and the last statement evaluated is the call to log.info(String) which returns void.
Use an explicit return or move/delete the log statement.
Using Powershell, I get a json snippet returned into my First variable (this always works fine);
# Initialise variables...
$nMessage_id = "";
$whatStatusJsonContent = "";
# Function https://abc.googleapis.com/abc/load call here and returns...
$whatStatusJsonContent = '{"message_id":9093813071099257562}'
Then I call the convert function into a temp variable like this;
$ResponseBody = ConvertFrom-Json $whatStatusJsonContent;
which puts the Json into a nice little data structure like this;
message_id
----------
9093813071099257562
From which I can select the value I want by calling this;
$nMessage_id = $ResponseBody.message_id;
Usually, this works fine and I get the value into my second variable;
$nMessage_id = 9093813071099257562
The problem is: Sometimes I get nothing in $nMessage_id, even though $whatStatusJsonContent is definitely logged as having the Json returned correctly from the function.
My question is: Do I have to ConvertFrom-Json, or can I read it raw from the First variable..?
COMBINED SOLUTION: Thanks to #mklement() and #Bernard-Moeskops
# Initialise variables...
$nMessage_id = "";
$whatStatusJsonContent = "";
# Function https://abc.googleapis.com/abc/load call here and returns...
$whatStatusJsonContent = '{"message_id":9093813071099257562}'
$ResponseBody = ConvertFrom-Json $whatStatusJsonContent;
if($ResponseBody.message_id){
# ConvertFrom-Json got the value!
$nMessage_id = $ResponseBody.message_id
}else{
# ConvertFrom-Json didn't work!
$nMessage_id = = ($whatStatusJsonContent -split '[:}]')[1]
}
There's nothing overtly wrong with your code.
ConvertFrom-Json should work as expected and return a [pscustomobject] instance with a .message_id property.
In your example, the message_id JSON property value is a number that is an integer, for which ConvertTo-Json automatically chooses a suitable integer data type as follows: the smallest signed type >= [int] (System.Int32)[1] that can accommodate the value ([int] -> [long] (System.Int64) -> [decimal] (System.Decimal)); the caveat is that if the value can't even fit into a [decimal], an - inexact - [double] is used.[2]
With the sample JSON in your question, [long] is chosen.
In a follow-up comment you state:
The routine makes over 1000 calls/hour and for most of them the Json comes back and the $nMessage_id is yielded perfectly. Then, suddenly, the $nMessage_id is empty, even though the Json is logged as coming back fine. So, somewhere in the ConvertFrom-Json or $ResponseBody.message_id the value is going missing...
I have no explanation, but if - for whatever reason - ConvertFrom-Json is the culprit, you can try string manipulation as a workaround to extract the message ID and see if that helps:
$whatStatusJsonContent = '{"message_id":9093813071099257562}'
# Extract the message_id property value as a *string*
# (which you can cast to a numeric type if/as needed).
$message_id = ($whatStatusJsonContent -split '[:}]')[1]
The above stores a string with content 9093813071099257562 in $message_id; note that, as written, the input string must have the exact format as above with respect to whitespace; while it is possible to make the text parsing more robust, not having to worry about format variations is one good reason to use a dedicated parser such as ConvertFrom-Json.
Another option is to try a different JSON parser to see if that helps.
Json.NET is the preeminent JSON parser in the .NET world (which now underlies the JSON cmdlets in PowerShell Core):
$whatStatusJsonContent = '{"message_id":9093813071099257562}'
$message_id = [NewtonSoft.Json.Linq.JObject]::Parse($whatStatusJsonContent).message_id.Value
Note: Json.NET - like ConvetFrom-Json in PowerShell _Core - commendably uses the arbitrary large [bigint] type as well once a number is too large to fit into a [long].
Use of the Json.NET assembly has the added advantage of better performance than the ConvertFrom-Json cmdlet.
In PowerShell Core, you can run the above code as-is (the assembly is preloaded); in Windows PowerShell you'll have to download the package via the link above and add the assembly (NewtonSoft.Json.dll) to your session with Add-Type -LiteralPath.
[1] Curiously, in PowerShell Core, as of (at least) v6.2.0, the smallest type chosen is [long] (System.Int64).
[2] More helpfully, PowerShell Core, as of (at least) v6.2.0, creates an arbitrarily large [bigint] (System.Numerics.BigInteger) instance once a value doesn't fit into a [long] anymore; that is, the [decimal] type is skipped altogether.
You are going to have to convert it, so that PowerShell can understand it. It will convert from a string to a PSCustomObject. Just check by asking the type of the variable before and after.
$ResponseBody.message_id.GetType()
If sometimes the output is nothing, you could do something like:
if($ResponseBody.message_id){
$nMessage_id = $ResponseBody.message_id
}else{
throw "No message id found"
}
Hope this helps.
I am trying to add a function to my Conky which prints the length of a string for debug purposes. The code, inside a file called test.lua, is pretty trivial:
function test(word)
return string.len(word)
end
...and I load it like this. In my conky.config section I have:
lua_load = '/home/xvlaze/test.lua',
lua_draw_hook_pre = 'test'
...in the conky.text section I have:
${lua test "fooo"}
...where test is the name of the function and fooo the string to test.
The expected result should be a printed 4 in Conky, but instead of that I get:
conky: llua_do_call: function conky_test execution failed: /home/xvlaze/test.lua:2: attempt to index a nil value (local 'string')
conky: llua_getstring: function conky_test didn't return a string, result discarded
I have browsed through the documentation, but I can't find anything. Does anybody know where the failure is?
Several guidances on how to implement functions in Conky:
First of all: YOU MUST USE conky_ BEFORE YOUR FUNCTION'S NAME.
Otherwise, you will get the following error when running your Conky:
attempt to call a nil value
Secondly: YOU MUST ALWAYS RETURN A VALUE.
I don't mind repeating it - it is crucial. Otherwise, you will get:
function foobar didn't return a string, result discarded
function_result
...in your terminal, and your Conky will be left empty of values related to your extra code. Nothing will be printed regarding your function.
Last but not least: YOU MUST ALWAYS CALL YOUR FUNCTION LIKE:
lua_load = '/path/to/function.lua',
-- Whatever content...
${lua function_name function_parameter1 function_parameterN} -- In case you use more than one parameter.
In summary, a dummy function template could be:
MAIN FILE (conky.conf):
conky.config = {
-- Whatever content... Lua styled comments.
lua_load = '/path/to/function.lua',
}
conky.text = [[
# Whatever content... In this section comments are started with '#'!
${lua function_name parameter}
]]
FUNCTION FILE:
function conky_function_name(parameter)
-- Whatever content... Remember this is Lua, not conky.text syntax. Always use '--' comments!
return whatever -- No return, no party. A function MUST always return something!
end
I write this code, but its not working, it gives this error
Call to a member function commit() on a non-object
Hear is my code
$datasource = $this->Arrear->getDataSource();
$datasource->begin();
if($this->Customar->saveField("total_bake",$amount) && $this->Arrear->save()){
$dataSource->commit();
return $this->redirect(array('action'=>'index'));
}else{
$dataSource->rollback();
$this->Session->setFlash('Data insert Failed','failure');
}
Variables in php(and hence in cakephp as well) are case-sensitive
http://php.net/manual/en/language.variables.basics.php
you have in your first line
$datasource = $this->Arrear->getDataSource();
but you are committing like
$dataSource->commit();
you have the data source assigned to $datasource, but not to $dataSource. The last variable even is not defined, that is why it is showing that error. So, you have to be sure you are using exactly the same variable (with same capitalization) in all places.
Spent my whole morning trying to find where my return value was getting garbled. Now that I've finally found where, I still have no idea why. Function looks like this:
function Run-RemoteCommand {
param(...) # params are $Remote (host) $Command $Credentials $Quiet (optional switch)
if($Quiet) {
$Process = New-Object System.Diagnostics.Process
$Process.StartInfo.UseShellExecute=$false
$Process.StartInfo.Domain=$Credentials.GetNetworkCredential().Domain
$Process.StartInfo.UserName=$Credentials.GetNetworkCredential().UserName
$Process.StartInfo.Password=$Credentials.Password
$Process.StartInfo.WindowStyle="Hidden"
$Process.StartInfo.FileName=$PSExec
$Process.StartInfo.Arguments=#("/acceptEULA",$Remote,"-s",$Command)
$Process.Start()
$Process.WaitForExit()
$result = $Process.ExitCode
return $result
} else {
...
}
}
What's odd is that I can step through this in a debugger and watch everything work fine. The command runs, $result is filled with the return code, but the calling function receives True appended to the return code (eg True0 on success). I even tried overriding the return value and just saying
return "false"
The calling function receives "Truefalse." All I can tell is that it's tied to $Process running. If I comment out $Process.Start(), the return code functions normally. Someone please save my sanity.
$Process.Start() returns a boolean value which is True if it succeeds. Remember that functions in PowerShell behave differently than standard programming languages. PowerShell functions "return" or more technically correct "output" any command output that isn't captured by a variable or redirected to a file or Out-Null. In this case change the Start line to:
[void]$Process.Start()
or
$Process.Start() | Out-Null
Check out this blog post for a deeper explanation.