Skip to main content
Known Participant
June 22, 2021
Answered

Element upload-id is undefined in a CFML structure referenced as part of an expression

  • June 22, 2021
  • 2 replies
  • 2444 views

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']#" />

    This topic has been closed for replies.
    Correct answer BKBK

    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.


    @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.

    2 replies

    BKBK
    Community Expert
    Community Expert
    June 23, 2021

    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']#" />

     

    raeltehAuthor
    Known Participant
    July 14, 2021

    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

    raeltehAuthor
    Known Participant
    July 19, 2021

    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>

     


    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."

    George____
    Inspiring
    June 22, 2021

    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.

    raeltehAuthor
    Known Participant
    June 22, 2021

    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>

    George____
    Inspiring
    June 22, 2021

    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.