AlpacaJS - How to access file uploaded in File Field in Handlebars - handlebars.js

I have a form with the following super basic file field:
Schema-
"file_upload": {
"type": "string"
}
Options-
"file_upload": {
"type": "file"
}
I want to access the file uploaded somehow, but particularly through Handlebars.js.
A regular field, say "file_checkbox" can be rendered using {{file_checkbox}} in handlebars but I can not figure out how to access the file.
Using basic javascript (document.getElementById('fieldId').files), I can see that the file has uploaded as anticipated.
But, trying to get the value of the Alpaca Form ($.alpaca($("#formDiv")).getValue()) yields the data from the regular fields (i.e. file_checkbox) and nothing from the file field.
When I submit the alpaca form all of the other data is properly saved, but again nothing from the file field (not even the name of the field with an empty/nil value)!
I've spent many hours searching and haven't found anything on the Alpaca website, Github Issues, or stack overflow! This is my first question so please let me know if there is any additional information I can provide.
Thank you!

That's normal with Alpaca, there will be no data for your file input set in your form data object, you should use the function selectionHandler to set the file(s) selected (you can use either File or Base64 data) to your form data like this :
"file-upload": {
"type": "file",
"selectionHandler": function(files, data) {
// files for multiple or use files[0] to get only one file
// and if you want to use base64 data you could use data
this.data = files;
}
}
And here's a fiddle for that.

Related

How can I get the source of a file using Cypress?

Selenium has a function called getPageSource that will get the source code of the page. I'm looking for the equivalent in Cypress.
I've tried
cy.get('html:root')
.eq(0)
.invoke('prop', 'outerHTML')
but, it doesn't really return the source of the page. As an example, the source contains ©, but the above cypress command shows it as ©. I want to see the actual source of the page, what I would see if I were to go to the server and open the file up in any plain text editor like notepad.
The naïve answer is to use string.replaceAll()
cy.get('html:root')
.eq(0)
.invoke('prop', 'outerHTML')
.then(pageSource => pageSource.replaceAll('©', '©'))
See dev.w3.org/html5/html-author/charref for a reference chart.
But I have a feeling there is a conversion function somewhere that does any and all occurrences.
Getting the equivalent of "View page source"*
cy.request(my-url)
.its('body') // NB the response body, not the body of your page
.then(content => {
// send content to validator.w3.org
// you can probably cy.visit('validator.w3.org') and manipulate the
// validation page, pasting in content value as required
})

Is there a way to reduce time complexity on the frontend with using Drupal json-api includes?

I'm currently working with an output from the Drupal json-api module and have noticed that the structure of an output forces an O(n^2) time complexity issue on the front by forcing the front end developers to reformat the json output given to them so an attachment can me in the same object as the entity it belongs to.
Example
So let's say I'm listing a bunch of categories with their thumbnails to be used on the front end. What a json output would normally look like for that is something like:
Normal category json structure
[
{
"uid":123,
"category_name":"cars",
"slug":"cars",
"thumbnail":"example.com/cars.jpg"
},
{
"uid":124,
"category_name":"sports",
"slug":"sports",
"thumbnail":"example.com/sports.jpg"
}
]
With drupal it seems that thumbnails are in their own includes separate from data creating an O(n^2). For example:
I make a get request using this endpoint:
example.com/jsonapi/taxonomy_term/genre?fields[taxonomy_term--genre]=name,path,field_genre_image,vid&include=field_genre_image
The structure of the data returned from the drupal json api module is going to be similar to this:
pseudo code for better readability
{
"data":[
{
"uid":123,
"category_name":"cars",
"slug":"cars",
"relationships":{
"thumbnail":{
"id":123
}
}
},
{
"uid":124,
"category_name":"sports",
"slug":"sports",
"relationships":{
"thumbnail":{
"id":124
}
}
}
],
"included":[
{
"type":"file",
"id":123,
"path":"example.com/cars.jpg"
},
{
"type":"file",
"id":124,
"path":"example.com/sports.jpg"
}
]
}
The problem with the drupal output is that I have to loop through the data and then in the data loop loop through the includes and attach each thumbnail to the category causing an O(n^2) on the frontend.
Is there a way for the frontend to request a category using the drupal json module to contain the thumbnail in the category like the normal json output above without having to restructure the json api on the frontend?
Please note I am not a drupal developer so the terminology I might use will be off.
JSON:API can output a list of entities and includes another list of entities (can have different types). each entity has UUID, so, accessing them can be O(logn) or even O(0) if you apply index to their UUID
So, you would have one loop to parse each of the included entity and store and index them (like SQLite), or simply loop over all included entities, build 1 array key by UUID and value is object of an entity

How to read connection string from .net core application which runs set of Nunit test cases

I have an appsettings.json file with the keys. I need to pass this to Nunit tests file.
how to do this?
{
"Mailing": {
"Smtp": {
"mailTo": "xxx#aperture-control.com",
"mailTo": "xxx",
"mailSubject": "Data Validation Report",
"mailBody": "Location Results",
"smtpHost": "xxx",
"smtpPort": "xx",
"smtpUser": "xx#aperture-control.com",
"smtpPassword": "xx",
}
},
"ElasticSettings": {
"ClusterUrl": "xxxx",
"jobIndex": "uklocation",
"host_versions": "uk"
}
}
``
You can pass the name of the file to NUnit as a run parameter.
If you are running with NUnit3-console, use the --testparam option to pass the name of the file. See https://docs.nunit.org/articles/nunit/running-tests/Console-Command-Line.html
If you are using the NUnit3 Visual Studio adapter, you will need to place the argument in a .runsettings file. In this case, each named parameter you wish to pass should be included as a parameter under RunSettings/TestRunParameters/Parameter
Within your test code, you access the value of the parameter using TestContext.TestParameters. One simple approach is to use `TestContext.TestParameters["myparamname"] but other options are shown in the docs at https://docs.nunit.org/articles/nunit/writing-tests/TestContext.html
I haven't told you where in your code to place this, since you haven't indicated exactly how you want to use the information. Since you will need to parse the file, you'll want to put it somewhere where it is only executed once, or a few times. Since the parameter is static, you can save extracted values in a singleton if you like.
UPDATE
The sample test you have shown (in a comment!) gives no extra info about how you are using the test case source. It's unclear whether only one test or many use it and whether variations are needed for different tests. So I'm giving an example that will work for the single test you have shown.
IEnumerable<TestCaseData> MyJSONData()
{
string file = TestContext.TestParameters["mySettingsFile"];
// Read your file and set name, query1 and query2
// Use whatever software you normally use to read it
yield return new TestCaseData(name, query1, query2);
}
[TestCaseSource(nameof(MyJSONData))]
public void MyTestCase(string name, string query1, string query2)
{
// Put your test code here
}
Running under nunit3-console.exe you would specify the option
--testParameter "mySettingsFile=PATH TO YOUR FILE"
You'll have better results with future questions if you provide a full example of code rather than trying to describe it in words.

Uncaught (in promise) FirebaseError: Invalid document reference. Document references must have an even number of segments

Well, My issue is different.. I created a modal form like this:
Modal Form
There is no issue at all and my data can be edited easily:
Updates with no errors
Now, I started to replace the text area with Vue2-editor plugin and the resulting design is like the following:
Vue-text-editor
I tried to modify the texts and save:
Error
Here is my updating mechanism:
updateProduct() {
// Update function has issues so I have to apply this work-around
this.$firestore.products.doc(this.product['.key']).set(this.product).then(() => {
this.$firestore.products.doc(this.activeItem).delete()}).then(()=>{
this.$refs.edit.hide()
toast.fire({
type: 'success',
title: 'Updated successfully'
});
});
},
Well, the firebase update function does not work at all. I have researched this, but in vain - this is the only working workaround for it.
Now I need to figure out what's wrong with that text editor.
Your problem is here:
this.$firestore.products.doc(this.product['.key'])
I don't know what the contents of this.product['.key'] is, but it's almost certainly not going to give you the name of a collection and the name of a document together. The only way you can reference a document is through a collection. Documents don't exist outside of collection. That's why the number of path segments in the string you pass to doc() must be even. It should be of the form "collection/document".
You will have to identify the collection you're writing to, and reference the path of the document using it.

SilverStripe 4.1 Email->addAttachment()?

I have a contact form that accepts a file input, I'd like to attach the file to the email that gets sent from the form.
Looking at the API reference isn't really helping, it states that the function expects a filepath with no clarification on anything beyond that.
The submit action will save a record of the into the database and this works correctly, something like:
$submission = MyDataObject::create();
$form->saveInto($submission);
$submission->write();
an Email object then gets created and sent. Both of these are functioning and working as expected.
Trying to attach the File I've tried:
$email->addAttachemnt($submission->MyFile()->Link());
which is the closest I can get to getting a filepath for the document. Dumping and pasting the resulting filepath being output by that call will download the form but that line throws an error and can't seem to locate the file.
I suspect that I'm misunderstanding what's supposed to be given to the function, clarification would be very much appreciated.
P.S. I don't currently have access to the code, I'm looking for some clarification on the function itself not an exact answer :).
In SilverStripe 4 the assets are abstracted away, so you can't guarantee that the file exists on your webserver. It generally will, but it could equally exist on a CDN somewhere for example.
When you handle files in SilverStripe 4 you should always use the contents of the file and whatever other metadata you have available, rather than relying on filesystem calls to load it.
This is how the silverstripe/userforms module attaches files to emails:
/** #var SilverStripe\Control\Email\Email $email */
$email->addAttachmentFromData(
$file->getString(), // stream of file contents
$file->getFilename(), // original filename
$file->getMimeType() // mime type
);
I would try $email->addAttachment($submission->MyFile()->Filename); If it doesn't work, you may need to prepend $_SERVER['DOCUMENT_ROOT'] to the filename.
$email->addAttachment($_SERVER['DOCUMENT_ROOT'] . $submission->MyFile()->Filename);

Resources