Migrating apps to version 9.4.0 and above

There are no breaking changes in 9.4.0 but along with this release there has been a change in the DataAccess api where it requires a Date type field to also be sent a Date type value or null.

If you have an application on an older version of CoreJs then you might see an error related to date down casting to string.

For some of yours submissions to the DataAccess API backend the error will be look like this:
Inconsistent data type (DateOnly<=>String) for field:

Changes to Date

In previous versions of CoreJs for an Optional date field if the user doesn’t fill it in then we were sending an empty string. As of version 9.4.0 we have changed this so we always send a null value if the value is not filled in. After you upgrade to 9.4.0 you shouldn’t need to make any code changes for this but just test it for your application.

There is a more detailed guide in the FAQ section for how to solve problems that you might face now that DataAccess doesn’t downcast a Date field to string when it receives a string as input.

Changes to Dropzone

In addition to the above change we added new options to the Dropzone:
An example from the Burial Permits app, here is a CoT Form Dropzone field:

The new field values are:
useJSONcustomMeta
This means the custom-meta header will be sent as a header and if you turned on “use_recaptcha” then the “captcha” key will be added into to that JSON object.

There new new options key that goes along with the above property:
getHeadersAsJson
This allows you to specify what the JSON in your custom-meta object should be. Note in side the custom-meta we will overwrite the “captch” key if it is in your object. To send a captcha token just turn use_recaptcha on.

Note: If you are using the above options in most cases you will be implementing a SSJS on Upload API to process the request. The detail for that are not covered here.

Example use case for useJSONcustomMeta:

Using it to send a JWT token for a upload file event with a Captcha token.

{ fields: [ { id: 'statementOfDeath', title: 'Statement of Death/Stillbirth and Supporting Forms', bindTo: 'statementOfDeath', prehelptext: 'Please upload the completed Statement of Death/Stillbirth form and all supporting forms.', type: 'dropzone', required: true, useJSONcustomMeta: true, use_recaptcha: true, recaptcha_sitekey: '/* @echo RECAPTCHA_SITEKEY */', options: { getHeadersAsJson: function() { return { "idToken": burialPermitApp.getCurrentIdToken() } }, retrieveAsFileDownload: true, addFileButtonName: 'Upload Forms', timeout: 0, acceptedFiles: 'application/pdf,.pdf,pdf,*.pdf',//"pdf/*,application/pdf,application/PDF", maxFiles: 1, maxFilesize: 5, url: '/*@echo ROOT_ENV_DA *//*@echo UPLOAD_URL */'+"bc_"+isBusinessCode+"_bc" } } ] }


There are few more options added:
retrieveAsFileDownload
downloadButtonClasses

Turning retrieveAsFileDownload option on means you will be handling the file download instead of the default which is an HTTP GET request to get the file (note we added target=”_blank” to the URL too in this release) . Turning this option on will change the link (element) into a button (element). This button will have a class as defined in the property downloadButtonClasses or the default value: js-dropzoneHandleFileDownload.
You can then choose to handle what should happen when that button is clicked by default we don’t add any type of event handling for this button click you will have to add it. This should give developers most flexibility.

I have provided some examples below of how this is used in the burial_permits app. This change is mainly for the VA finding that we are allowed to get files by sending the SID in the URL.

Use case 1: If you don’t want to make a download request:

'click .js-dropzoneHandleFileDownload': function(event) { event.preventDefault(); $(event.currentTarget).attr("disabled", true); let nameOfFile = $(event.currentTarget).data("dz_name"); CotApp.showModal({ preset:'alert', title: 'Unauthorized', body: `<p>The file ${nameOfFile} was uploaded to the server. You are not authorized to download this file.</p>`, modalSize: 'modal-md', originatingElement: $(event.currentTarget) }); $(event.currentTarget).attr("disabled", false); return false; }

Use case 2: You want to allow for file download and want to send some authentication information along like the SID. To avoid browser saving authentication information in the URL history we want to send that information in the header or the body of the request.

$("#maincontent").off('click', '.js-dropzoneHandleFileDownload').on('click', '.js-dropzoneHandleFileDownload', function(event) { event.preventDefault(); $(event.currentTarget).attr("disabled", true); let linkToFile = config.httpHost.app[httpHost] + $(event.currentTarget).data("dz_filelink"); let nameOfFile = $(event.currentTarget).data("dz_name"); var myHeaders = new Headers(); myHeaders.append("Authorization", Cookies.get(config.default_repo + ".sid")); myHeaders.append("Cache-Control", "no-store"); var requestOptions = { method: 'GET', headers: myHeaders }; fetch(linkToFile, requestOptions) .then(response => { if (response.status === 200) { return response.blob(); } else { throw({"error": response, "status": response.status}); } }) .then(blob => { var url = window.URL.createObjectURL(blob); var a = document.createElement('a'); a.href = url; a.download = nameOfFile; document.body.appendChild(a); // we need to append the element to the dom -> otherwise it will not work in firefox a.click(); a.remove(); //afterwards we remove the element again $(event.currentTarget).attr("disabled", false); }) .catch(error => { console.log('file download error', error); if (error.status === 401) { cot_app.showModal({ preset:'alert', title: 'Unauthorized', body: `<p>You are not authorized to download this file. Please re-login and try again.</p>`, modalSize: 'modal-md', originatingElement: $(event.currentTarget) }); } else { cot_app.showModal({ preset:'alert', title: 'System Error', body: `<p>There was an error processing your file download request. Please re-login and try again. If the issue continues please report this problem.</p>`, modalSize: 'modal-md', originatingElement: $(event.currentTarget) }); } $(event.currentTarget).attr("disabled", false); }); });