Copy link to clipboard
Copied
Hi Everyone,
I have a few kiosks that I use this code for and over the last few days I keep receiving this error "Element upload-id is undefined in a CFML structure referenced as part of an expression." on line 93 which I have in bold and Italic. Nothing has changed at all with those code. Here are a few lines from it before and after the error.
</cfoutput>
<cfhttp url="#baseurl#/api/recipients/upload" method="post" result="uploadresult" >
<cfhttpparam type="header" name="Authorization" value="Bearer #token.access_token#" />
<cfhttpparam type="FormField" name="stage" value="1" />
<cfhttpparam type="FormField" name="updateAll" value="1" />
<cfhttpparam type="FormField" name="uniqueUploadId" value="#result['upload-id']#" />
</cfhttp>
<!---cfdump var="#uploadresult#" / --->
<cfoutput>
Requesting stage 3 processing<BR>
</cfoutput>
<cfhttp url="#baseurl#/api/recipients/upload" method="post" result="uploadresult" >
<cfhttpparam type="header" name="Authorization" value="Bearer #token.access_token#" />
<cfhttpparam type="FormField" name="Stage" value="3" />
<cfhttpparam type="FormField" name="updateAll" value="0" />
<cfhttpparam type="FormField" name="uniqueUploadId" value="#result['upload-id']#" />
@raelteh ,
During testing, log every cfdump to file and study the results. For example, by using something like
<!--- Displays the dump --->
<cfdump var="#uploadresult#" label="uploadresult">
<!--- Logs the dump as HTML file in same directory --->
<cfdump var="#uploadresult#" label="uploadresult" format="html" output="#expandPath('uploadresult.html')#">
You should be able to see at which stage errors occur.
Correct the errors one by by one. Then repeat the tests until you no longer get any e
...Copy link to clipboard
Copied
Your issue is going to be above that. The error is telling you that upload-id doesn't exist within the result structure.
If it's being passed in from another page the issue may be that page isn't sending it sometimes. If it's generated on that page it may be that you have some decision logic that is sometimes not defining it.
Copy link to clipboard
Copied
Hi George,
Thank you for your response. Should I be looking at the previous =result lines to see if one of them is not defining it? This is my first time seeing the file and I'm unsure what I should be looking for.
<cfinclude template="../thd/DataSourceName.cfm" /> <!--- SITE SPECIFIC - point to relative path of THD folder (test or production) --->
<cfsetting requestTimeOut = "3600">
<cftry>
<cfquery datasource="#connection_string#" name="qry">
SELECT DISTINCT RTRIM(tblStudents.FirstName + ' ' + ISNULL(LEFT(tblStudents.MI, 1),'')) + ',' +
tblStudents.LastName + ',' +
IsNull(tblStudents.Email,'') + ',' +
tblStudents.BoxNumber + ',' +
tblStudents.StudentNumber + ',' +
CASE WHEN UPPER(tblStudents.NAME_TAG) <> UPPER(tblStudents.FirstName) THEN tblStudents.NAME_TAG ELSE tblStudents.FirstName END +
',,,,,,,,,,Student,' +
CASE WHEN LEN(IsNull(tblStudents.email,'')) = 0 THEN 'No' ELSE 'Yes' END + ',' +
'No'+ ',Yes,' AS DataLine
FROM tblStudents
LEFT OUTER JOIN tblStudentTimeFrames
ON tblStudents.StudentID = tblStudentTimeFrames.StudentID
LEFT JOIN tblStudentGroupTimeFrame SGTF
ON tblStudentTimeFrames.TimeFrameID = SGTF.TimeFrameID
AND tblStudentTimeFrames.StudentGroupID = SGTF.StudentGroupID
LEFT OUTER JOIN tblStudentGroup
ON SGTF.StudentGroupID = tblStudentGroup.StudentGroupID
LEFT JOIN tblTimeFrame
ON tblStudentTimeFrames.TimeFrameID = tblTimeFrame.TimeFrameID
WHERE tblStudents.BoxNumber <> '' and tblStudents.BoxNumber is not Null and
not tblStudentGroup.StudentGroup in ('hd', 'Hs', 'dgHD')
</cfquery>
<cfoutput>
Query returned #qry.RecordCount# row(s).<BR>
</cfoutput>
<cfif qry.RecordCount GT 0>
<cfset baseurl = "https://website" /> <!--- SITE SPECIFIC - URL for site's EZTrackit API location --->
<cfoutput>
Requesting authorization token<BR>
</cfoutput>
<cfhttp url="#baseurl#/api/users/auth" method="post" result="authresult" >
<cfhttpparam type="header" name="Accept-Encoding" value="*" /> <!--- NAME --->
<cfhttpparam type="Header" name="TE" value="deflate;q=0"> <!--- NAME --->
<cfhttpparam type="FormField" name="username" value="randomapi" /> <!--- SITE SPECIFIC - Username for API calls --->
<cfhttpparam type="FormField" name="password" value="passwordvalue" /> <!--- SITE SPECIFIC - Password for API calls --->
<cfhttpparam type="FormField" name="client_id" value="random numbers" /> <!--- SITE SPECIFIC - Client ID for API Calls --->
</cfhttp>
<!--- cfdump var="#authresult#" / --->
<cfif authresult.StatusCode NEQ "403 Forbidden">
<cfset token = deserializeJSON(authresult.filecontent) />
<cfset export_file = "randomfilelocation.csv"> <!--- SITE SPECIFIC - Location to store csv files that are created --->
<cfoutput>
<!---
Authorization key: #authresult.filecontent#<BR>
Header Authorization: Bearer #token.access_token#<BR>
--->
Building file content (#export_file#)<BR>
</cfoutput>
<cffile action="write" file="#export_file#" output="First Name,Last Name,Email Id,Mailbox Id,Internal ID,Joint A/C holder,Company/Department,Address1,Address2,City,State,Postal code/ Zip Code,Country(ISO Code),Phone Number,Mobile,Recipient Type,Email Notification ?,SMS Notification ?,Active,Notes"/>
<cfloop query="#qry#">
<cffile action="append" file="#export_file#" output="#qry.DataLine#"/>
</cfloop>
<cfoutput>
Sending file content<BR>
</cfoutput>
<cfhttp url="#baseurl#/api/recipients/upload" method="post" result="uploadresult" >
<cfhttpparam type="header" name="Authorization" value="Bearer #token.access_token#" />
<cfhttpparam type="file" name="recipientFile" file="#export_file#" />
<cfhttpparam type="FormField" name="stage" value="0" />
<cfhttpparam type="FormField" name="updateAll" value="1" />
</cfhttp>
<!--- cfdump var="#uploadresult#" / --->
<cfset result = DeserializeJSON(uploadresult.filecontent) />
<!---<cfdump var="#result#" abort="yes"/>--->
<cfoutput>
Requesting stage 1 results<BR>
</cfoutput>
Copy link to clipboard
Copied
I pulled the API documentation for EZTrackit off the web and it shows that on a failure something like this will be returned.
{ "code": 400, "message": "Validation Failed", "errors": { "recipient": { "firstName": [ { "message": "First name can not be empty"}]}}
on success this is returned
{ “upload-id”: XYX”, “total-records”: ABC }
I suspect that you're getting the 400 code on some calls, and since it's not being checked for the page doesn't throw an error until you get down to result.upload-id.
Of course the easy way to test this if you can duplicate the error is to uncomment those cfdumps. If you can't realiably generate the error you could just check for the missing upload-id and then dump the results. Something like this
<cfset result = DeserializeJSON(uploadresult.filecontent) />
<cfif NOT StructKeyExists(Result,"upload-id")>
<cfdump var="#result#" abort="yes">
</cfif>
If you need to run this in production you can remove the abort and instead have the output go to a file. Then just check later for the file.
Copy link to clipboard
Copied
There is indeed an error. The code contains only one struct named result. And that struct is a standard attribute of the cfhttp tag. Its keys are Mimetype,Errordetail,Statuscode,Filecontent,Responseheader,Text,Charset,Header - none of which is upload-id.
Is there prior to this code, perhaps a custom struct that also shares the same name ("result"), and that has the key upload-id? If so, rename it.
From the look of things, my guess is that that custom struct is in fact form. If so, then that line should be:
<cfhttpparam type="FormField" name="uniqueUploadId" value="#form['upload-id']#" />
Copy link to clipboard
Copied
Thank you for the help. I changed line 93 to what you suggested and this was the error output.
Error Message: Element upload-id is undefined in a Java object of type class coldfusion.filter.FormScope.
Error Detail: File Path: D:\wwwroot\THD_ADMIN\DIM_files\EZTrackit_Export.cfm Line Number: 93
Copy link to clipboard
Copied
OK, the form struct doesn't have a field called 'upload-id'. I have had another look at your code, gained greater insight. Also from George's remarks.
The puzzle now seems transparent.
<!---
uploadresult = the result of a cfhttp request to #baseurl#/api/recipients/upload.
result = the value of uploadresult, represented as a struct.
upload-id = one of the keys of this struct.
--->
<cfset result = DeserializeJSON(uploadresult.filecontent) />
This implies that result["upload-id"] can only exist after you run the cfhttp to #baseurl#/api/recipients/upload.
There is therefore a contradiction when you do the following:
<cfhttp url="#baseurl#/api/recipients/upload" method="post" result="uploadresult" >
...
<cfhttpparam type="FormField" name="uniqueUploadId" value="#result['upload-id']#" />
It is contradictory because you are trying to use the variable result['upload-id'] within the very cfhttp call that is supposed to create it.
Copy link to clipboard
Copied
Thank you for your help BKBK. Am I able to modify the code and remove the cfhttp call entirely from that line so its not a contradiction? If I add the string #baseurl#/api/recipients/upload first and have the uploadid follow the line there after would that work since the results would be pulled from the first line?
Copy link to clipboard
Copied
If I add the string #baseurl#/api/recipients/upload first and have the uploadid follow the line there after would that work since the results would be pulled from the first line?
By @raelteh
Yes, indeed.
1) <cfhttp>... </cfhttp> without including the cfhttpparam called uniqueUploadId.
2) Obtain upload-id from the result.
3) Use result['upload-id'] as a cfhttpparam value in subsequent cfhttp calls.
Copy link to clipboard
Copied
So the new line should look like this when I remove uniqueUploadid
<cfhttpparam type="FormField" value="#result['upload-id']#" />
Then once i get the output of what upload id is I supplement the old tag uploadid with the new value and replace it?
Copy link to clipboard
Copied
@BKBK: 1) <cfhttp>... </cfhttp> without including the cfhttpparam called uniqueUploadId.
By that, I mean, without that entire cfhttpparam tag
Copy link to clipboard
Copied
Can I just remove this line entirely: <cfhttpparam type="FormField" name="uniqueUploadId" value="#result['upload-id']#" />
Or should I just be removing <cfhttpparam type="FormField" from the line
and remove the end of it at </cfhttp> ?
<cfhttp url="#baseurl#/api/recipients/upload" method="post" result="uploadresult" >
<cfhttpparam type="header" name="Authorization" value="Bearer #token.access_token#" />
<cfhttpparam type="FormField" name="stage" value="1" />
<cfhttpparam type="FormField" name="updateAll" value="1" />
<cfhttpparam type="FormField" name="uniqueUploadId" value="#form['upload-id']#" />
</cfhttp>
Copy link to clipboard
Copied
Yes, remove the line entirely.
Reason: you will obtain an upload-id only after you upload. That is, after the call
<cfhttp url="#baseurl#/api/recipients/upload" method="post" result="uploadresult" >
...
<cfhttp>
Following the cfhttp call, you may then obtain the upload ID using your original code, namely:
<cfset result = DeserializeJSON(uploadresult.filecontent) />
<cfif structKeyExists(result, 'upload-id')>
<cfset uploadID = result['upload-id']
</cfif>
Copy link to clipboard
Copied
So ideally once I remove line 93 it will post what the upload id is, then once i find out what that upload id is I can then impliment it into the code fixing the error. I believe AWS generates and returns the upload ID.
I found this on the api guidelines "Stage 0(zero) : In this stage client application uploads the recipient file and in return back-end sends total number of records and unique upload id."
Copy link to clipboard
Copied
I found this on the api guidelines "Stage 0(zero) : In this stage client application uploads the recipient file and in return back-end sends total number of records and unique upload id."
By @raelteh
Indeed. 🙂
Copy link to clipboard
Copied
I had the script run over night and I received the same error. "Element upload-id is undefined in a CFML structure referenced as part of an expression."
The only difference is now the line number changed to 103. The line is the same as the previous line 93 that I deleted before. Should I delete line 103 as well and have it run again overnight? I'm not sure how I would find the output from the script to see what the upload id would be in order to replace that value.
Copy link to clipboard
Copied
OK. We're getting there. 🙂 Please share the code from <cfhttp> right up until the line where the errror occurs.
Copy link to clipboard
Copied
Here is the code from line 94 until the new error at line 103. I also noticed on line 103 I didnt change the value of results to form like I did with the previous line 93.
</cfhttp>
<!---cfdump var="#uploadresult#" / --->
<cfoutput>
Requesting stage 3 processing<BR>
</cfoutput>
<cfhttp url="#baseurl#/api/recipients/upload" method="post" result="uploadresult" >
<cfhttpparam type="header" name="Authorization" value="Bearer #token.access_token#" />
<cfhttpparam type="FormField" name="Stage" value="3" />
<cfhttpparam type="FormField" name="updateAll" value="0" />
<cfhttpparam type="FormField" name="uniqueUploadId" value="#result['upload-id']#" />
Copy link to clipboard
Copied
Here is the code from line 94 until the new error at line 103. I also noticed on line 103 I didnt change the value of results to form like I did with the previous line 93.
</cfhttp>
<!---cfdump var="#uploadresult#" / --->
<cfoutput>
Requesting stage 3 processing<BR>
</cfoutput>
<cfhttp url="#baseurl#/api/recipients/upload" method="post" result="uploadresult" >
<cfhttpparam type="header" name="Authorization" value="Bearer #token.access_token#" />
<cfhttpparam type="FormField" name="Stage" value="3" />
<cfhttpparam type="FormField" name="updateAll" value="0" />
<cfhttpparam type="FormField" name="uniqueUploadId" value="#result['upload-id']#" />
By @raelteh
This code takes us back to where we started! 😞
Did you follow any of the suggestions?
Let's move forward. Suggestion:
Replace the commented line.
<!---cfdump var="#uploadresult#" / --->
with the following code
<cfdump var="#uploadresult#" label="uploadresult">
<cfset result = DeserializeJSON(uploadresult.filecontent)>
<cfdump var="#result#" label="result">
<cfif structKeyExists(result, 'upload-id')>
uploadID: <cfoutput>#result['upload-id']#</cfoutput>
</cfif>
<cfabort>
What do you get?
If structures are dumped, do you see any key named upload-id? Or perhaps upload_id?
In any case, what are the names of the keys in the structures?
Copy link to clipboard
Copied
Raelteh, I guess it'll be clearer if you repost the code, but my guess is you removed the uniqueUploadID from Stage 1, but that should be there. The Stage 0 call returns the upload-id, which is then used in stages 1 - 3.
I still think you're getting an error on your Stage 0 and not seeing it because you're not checking for it. Therefore the code proceeds to the next step even though no upload-id was returned. I recommend taking a look at the API guide and stepping through your code and looking at the examples in the guide.
After the closing </cfhttp> on your Stage = 0 call put a cfdump to save the returned result to a file. For example
<cfdump var="#uploadresults#" output="C:\temp\Stage0.html" format="HTML">
You'll need to set the output path to wherever you want the file to be put, keep in mind the CF service has to have access to that folder. If you want to put the file in the same folder as your CFM page you can use getCurrentTemplatePath. For example output="#GetDirectoryFromPath( GetCurrentTemplatePath() )#Stage0.html".
Of course if you're manually running this you can just cfdump it to the screen, but dumping to a file will allow it to run overnight and you can look at the Stage0.html file in the morning. I think you'll see in the Stage0.html file a response that matches the failure condition. The message in the failure response should tell you why it's failing.
Copy link to clipboard
Copied
@raelteh ,
During testing, log every cfdump to file and study the results. For example, by using something like
<!--- Displays the dump --->
<cfdump var="#uploadresult#" label="uploadresult">
<!--- Logs the dump as HTML file in same directory --->
<cfdump var="#uploadresult#" label="uploadresult" format="html" output="#expandPath('uploadresult.html')#">
You should be able to see at which stage errors occur.
Correct the errors one by by one. Then repeat the tests until you no longer get any errors.