Check if argument exist in ColdFusion - ajax

I have a question about arguments that are passed with ajax in coldfusion. So I have three arguments that I'm passing date1, date2 and meetingDate. I have to compare three of these arguments and return the string based on the dates. Here is my logic:
<cfset sigDate1 = dateFormat(trim(arguments.date1),'yyyy/mm/dd')>
<cfset sigDate2 = dateFormat(trim(arguments.date2),'yyyy/mm/dd')>
<cfset meetDate = dateFormat(URLDecode(arguments.meetingDate),'yyyy/mm/dd')>
<cfelseif (sigDate1 LT meetDate) OR (sigDate2 LT meetDate)>
<cfset myResult = "blockDate">
<cfelse>
My current code has one problem, if I just pass one of these two dates(date1 or date2) I will always get "blockDate" returned with my ajax function. I detected the problem and if I just pass date1 but not date2 my elseif still will be executed no matter what. So I was trying to fix this problem with using one extra cfif and check if my date1 and date2 isDefined but that did not fix the problem. If anyone have any idea how to fix this bugg please let me know.
Thanks in advance.

There are a couple different ways to handle this. As I understand it; the arguments always exist, but you are concerned they may have blank values.
Here are some ideas you should be able to adapt to get you started:
use defaults
<cfset sigDate1 = iif(isDate(trim(arguments.date1),'dateFormat(trim(arguments.date1),'yyyy/mm/dd')','[default value]')/>
<cfset sigDate2 = iif(isDate(trim(arguments.date2),'dateFormat(trim(arguments.date2),'yyyy/mm/dd')','[default value]')/>
<cfset meetDate = iif(isDate(trim(URLDecode(arguments.meetingDate),'dateFormat(trim(URLDecode(arguments.meetingDate),'yyyy/mm/dd')','[default value]')/>
or (test dates)
<cfif isDate(trim(arguments.date1)) and isDate(trim(arguments.date2)) and isDate(URLDecode(arguments.meetingDate))>
<cfset sigDate1 = dateFormat(trim(arguments.date1),'yyyy/mm/dd')/>
<cfset sigDate2 = dateFormat(trim(arguments.date2),'yyyy/mm/dd')/>
<cfset meetDate = dateFormat(URLDecode(arguments.meetingDate),'yyyy/mm/dd')/>
<cfelse>
<--- error code --->
</cfif>
or (use try block)
<cftry>
<cfset sigDate1 = dateFormat(trim(arguments.date1),'yyyy/mm/dd')/>
<cfset sigDate2 = dateFormat(trim(arguments.date2),'yyyy/mm/dd')/>
<cfset meetDate = dateFormat(URLDecode(arguments.meetingDate),'yyyy/mm/dd')/>
<cfcatch type="expression">
<--- error code --->
</cfcatch>
</cftry>

Related

I have a need to see all session scope for all logged in users in ColdFusion2018

I start with this find;
<cfscript>
app = application.getApplicationSettings().name;
sessionCollection = application.sessionTracker.getSessionCollection(app);
</cfscript>
and then attempt to loop thru the collection;
<cfloop collection="#sessionCollection#" item="i">
#StructFind(i, 'CurrentAction')#
</cfloop>
which fails with;
You have attempted to dereference a scalar variable of type class java.lang.String as a structure with members.
I have tried
#CurrentAction[i]#
which fails with;
Variable CURRENTACTION is undefined.
when I know for a fact it exists
(https://ibb.co/ZJwsKFS)
Ive tried dot notation as well.
The purpose is to identify an ajax listener activity for one user, and affect an action on another specific user as a response. I am under the impression I can send an action by sessionID end user. Please feel free to let me know if this is NOT possible.
So this code:
<cfset x = {
a = 1
, b = 2
, c = 3
}>
<cfoutput>
<cfloop collection="#x#" item="i">
<li>#i#</li>
</cfloop>
</cfoutput>
Outputs the following:
A
B
C
Which means that i is the key of the struct defined in the collection attribute. Your code is trying to find a key in the collection (struct), but you're referencing the wrong variable.
To find the value of B, you would do StructFind(x, "b"). You don't need the cfloop either, you just need to check if the key exists, then get the value.
<cfset someVariable = "">
<cfif structKeyExists(x, "b")>
<cfset someVariable = structFind(x, "b")>
</cfif>

ArrayAppend returning boolean instead of array

OK I have been struggling with this for sometime and I figured I would go back to the basics and try and figure out my error, as I get the same error here as I do down the line.
Here is my Code:
<cfparam name="session.cart" default="arrayNew(1)">
<cfset session.cart = arrayAppend(session.cart,structNew() )>
<cfset thisCartItem = arraylen(session.cart)>
<cfset session.cart[thisCartItem].itemID = "X">
<cfset session.cart[thisCartItem].quantity = "X">
<cfset session.cart[thisCartItem].itemName = "X">
<cfdump var="#session.cart#">
Here is my error:
Object of type class java.lang.Boolean cannot be used as an array
The error means exactly what it says. The variable session.cart is not an array. It is a boolean value. If you read the ArrayAppend documentation it explains why. The function modifies the array in place and returns a boolean value:
Returns True, on successful completion.
By capturing the result here, you are actually setting the cart value to true/false:
<!--- Note the addition of the pound signs in the CFPARAM --->
<cfparam name="session.cart" default="#arrayNew(1)#">
<cfset session.cart = arrayAppend(session.cart, structNew())>
Having said that, you could simplify the code a lot by using the shorthand syntax supported in all recent versions of CF ie {} - new structure and [] - new array. To create a new array:
<cfset session.cart = []>
To append one or more structures to the end of that array:
<!--- append first structure to array --->
<cfset ArrayAppend( session.cart
, { itemID = "X", quantity = "X", itemName = "X" }
)>
<!--- append second structure to array --->
<cfset ArrayAppend( session.cart
, { itemID = "Y", quantity = "Y", itemName = "Y" }
)>

How to query XML by Attribute Index Using XMLDom

I am trying to query an XML File in order to get the attribute values for a specific element.
This works fine when the element has a unique set of attribute e.g.
<parent>
<child code="REWC" curr="PLN" amt="1000"/>
</parent>
In order to query the above I use:
object = Microsoft.XMLDOM
getElementsByTagName OR selectSingleNode method
Once I have that, I run the 'getAttribute' method, which gives me what I need
code snippet:
Set ElementValue = m_objXmlDom.selectSingleNode("//Txn[" & p_intIndex & "]/" & p_strElementName & " ")
'set attribute value
strAttributeValue = ElementValue.getAttribute(p_strAttributeName)
However, I am now in a situation where the XML looks as per below:
<parent>
<child code="REWC" curr="PLN" amt="1000"/>
<child code="xxxx" curr="EUR" amt="1500"/>
<child code="yyyy" curr="GBP" amt="1700"/>
</parent>
Is there a simple way to iterate through each attribute, get the value, and then I can do something with it.
I am looking for something like:
.getAttribute(code)[0]
.getAttribute(code)[1]
.getAttribute(code)[2]
Something like the above will print out all the values for all attributes. But Im not to sure how to index at the attribute level.
Any help would be great. I am using VBScript with Microsoft XMLDom.
Ok, I have gotten around the issue now by doing a for loop in order to iterate
over all of the elements that have been returned, and then reading in each attribute.
If the attribute matches the one I am looking for then I exit the for loop.
if there is a better way of doing this, then please share any answers, in the meantime my
code is working as per below.
Code snippet:
Set Data = m_objXmlDom.getElementsByTagName(".//Txn[" & p_intIndex & "]/" & p_strElementName & "/" & p_strSubElementName & "")
'loop through each one
For Each DataItem in Data
strTemp1 = DataItem.getAttribute("code")
strTemp2 = DataItem.getAttribute("curr")
strTemp3 = DataItem.getAttribute("amt")
If strTemp1 = strExpectedValue Then
'set the values
m_strTemp1 = strTemp1
m_strTemp2 = strTemp2
m_strTemp3 = strTemp3
'set pass flag
blnDataFound = True
Exit For
End If
Next

Can I store a struct in a Coldfusion session variable?

I'm passing a struct to a CF Custom Tag. I'd like the CFM page that is this custom tag to assign this struct to a dynamically created session variable. Creating the session variable works when assigning it to a simple value such as a number, but fails when assigning it to the struct in the way I'm doing it below.
<cfset Evaluate("SESSION.myVar#ATTRIBUTES.count# = #ATTRIBUTES.myStruct#")>
I thought this was possible, but when I try to do so I get an error:
Complex object types cannot be converted to simple values.
This is how the struct is created:
<cfset testStruct = StructNew()>
<cfset testStruct.something = 2>
And passed through the custom tag:
<cf_myTag myStruct="#testStruct#" count="#i#">
I think the Evaluate portion is messing things up here.
As Leigh says, use array notation rather than Evaluate() to create your dynamically named session variable:
<cfset SESSION[ "myVar" & ATTRIBUTES.count ] = ATTRIBUTES.myStruct>
Yes you can,
Just use the duplicate method
<cfset SESSION.myVar = duplicate(ATTRIBUTES.myStruct) />
yes, you can just do the following:
note I'm using a cflock here to avoid any potential race conditions.
<cflock scope="session" throwontimeout="true" timeout="5" type="exclusive">
<cfset session["myVar" & ATTRIBUTES.count] = attributes.myStruct />
</cflock>
The issue above is the evaluate statement. It's trying to evaulate the structure as a simple value in the string, and then evaluate the string.
You can get around evaulate entirely. The reason is you want a dynamically named session variable?

Cast as integer in ColdFusion; sanitizing variables

I'm rusty at ColdFusion, I've been used to PHP for so long. What I want to do is something like this:
<?php
$id = (isset($_GET['id'])) ? (int)$_GET['id'] : 0;
?>
Basically, check for a url parameter called id and if it exists make sure it's an integer so I can safely use it in database queries. If it ends up zero, that's fine too.
I have:
<cfscript>
if (IsDefined("URL.id") AND IsNumeric(URL.id)) {
id = int(URL.id);
} else {
id = 0;
}
</cfscript>
This is working, but is awfully messy. Is there a better way to do this?
Recent versions of ColdFusion also have a ternary conditional operator:
<cfset id = (structKeyExists(URL, "id") and isNumeric(URL.id)) ? int(URL.id) : 0>
I would use cfparam. I'd also scope explicitly, but that's not necessary. I wouldn't use the IIF() function, because it makes use of evaluate(), which can be problematic, I'd also avoid DE() for the same reason. In this case, it won't be an issue, but I avoid them on general principle in any situation where it's not absolutely necessary. I've been using CF for a few years now, and it hasn't been necessary yet.
<cfparam name="url.id" default="0" />
<cfif isNumeric(url.id)>
<cfset local.id = int(url.id) />
<cfelse>
<cfset local.id = 0 />
</cfif>
To me, the simplest way to ensure your variable is an integer is to wrap the variable in val().
It attempts to parse the string and extract any integer found (at the beginning of the string). If none is found it returns 0.
If TestValue = "234A56?7'", Val(TestValue) returns 234.
If TestValue = "234'5678'9?'", Val(TestValue) returns 234.
If TestValue = "BG234", Val(TestValue) returns the value 0, (not an error).
If TestValue = "0", Val(TestValue) returns the value 0, (not an error).
See http://cfquickdocs.com/cf8/#Val
Apologies for raising an old thread but came up with this same question and found a simple solution that might help others with this issue
NumberFormat(URL.id)
There are also various masks that you can specify in different scenarios
ColdFusion Reference
A formatted number value:
If no mask is specified, returns the value as an integer with a thousands separator.
If the parameter value is "" (an empty string), returns 0.
http://help.adobe.com/livedocs/coldfusion/8/htmldocs/help.html?content=functions_m-r_08.html
You might also look into cfparam.
<cftry>
<cfparam name="url.id" default="0" type="integer">
<cfcatch>
<!--- log? etc --->
<cfset url.id = 0>
</cfcatch>
</cftry>
You can use IIF. It's cool.
<cfset id = IIf(IsDefined("URL.id") AND Int(URL.id), Int(URL.id), DE("0"))>

Resources