Additional parameters when using intel.xdk.file.uploadToServer? - javascript

I'm using Intel XDK to create a smartphone application. Currently I'm uploading a captured photograph by using intel.xdk.file.uploadToServer as shown in their documentation. This is working fully, however I would like to send additional parameters to the back-end (PHP) other than just those required by the 'uploadToServer' function.
What should I do / use?

The uploadToServer file API does not allow you to specify additional parameters than what is documented.
I would use Parse JavaScript APIs that allow you to easily save an object and link to an uploaded file, here is an example:
Parse.initialize("YOUR KEY GOES HERE"); //API key
//whatever you want to call your storage object
var PhotoDetails = Parse.Object.extend("PhotoDetails");
//create new instance of your Parse Object
var photoDetails = new PhotoDetails();
//you can add each param separately and save
photoDetails.set("paramname", "value");
photoDetails.save();
//or use object literal notation
photoDetails.save({category: "landscape",
description: "a very cool photo",
location: "33.38453, -28.234234"
}).then(function(object) {
alert("Photo Recorded!);
});
You can also store the actual photo or filetype in the cloud up to 10MB per file. Parse determines the file type by the file extension or you can specify the type in the optional third param below:
//see https://parse.com/docs/js_guide#files
//for base 64 or HTML file input examples
var parseFile = new Parse.File("myphoto.jpg", fileData, "image/jpg");
parseFile.save().then(function() {
alert("The file has been saved to Parse.");
}, function(error) {
console.log("The file either could not be read, or could not be saved to Parse.");
});
You can associate a Parse File with a Parse Object by using:
photoDetails.set("photoFile", file);
photoDetails.save();
Then in the cloud you can login to Parse and you will see your object type in the Data Browser view with your photo image and all the other params you specified.
For more info see: https://parse.com/docs/js_guide#javascript_guide

Related

Getting a file URL from Sanity out of a blocks array

I'm building a website using Next JS and Sanity for the CMS. Sanity has built-in schemas for images but not for video, so a video needs to be uploaded with the File schema. The docs suggest that to get a file URL to be used on the front-end you should use the query language GROQ to make this conversion at the request like so:
// GROQ query
*[_type == 'movie'] {
title,
"manuscriptURL": manuscript.asset->url
}
But since I am using the File schema to embed short auto-looping videos into rich text content using the Blocks schema, I don't have the luxury of converting URLs at the request and need to do it dynamically as the blocks array data is being parsed for the #portabletext/react component.
Basically, what I get back for the file is simply an asset reference with the following data:
{
"_type": "file",
"asset": {
"_ref": "file-e4e61f3b231cca8e3339e96e050aee428009c777-gif",
"_type": "reference"
}
}
When I then use Sanity's own #sanity/asset-utils package to get a file URL using their buildFileUrl() function, I get a URL that is undefined for that asset where PROJECT_ID and DATASET are the correct values:
https://cdn.sanity.io/files/[PROJECT_ID]/[DATASET]/undefined.undefined
Here is the function I made, using their package's file URL function, to get the asset URL, which returns the URL above with the undefined values:
export function getSanityFileUrl(sanityFile) {
const fileUrl = buildFileUrl(sanityFile.asset, {projectId: sanityConfig.projectId, dataset: sanityConfig.dataset})
console.log(fileUrl)
}
Thanks and anything helps!
I found the solution. The buildFileUrl() function exported by #sanity/asset-utils expects a different asset object. Instead, a user in this situation should use the getFileAsset() function which can accept a reference to the file.

Is there a way to Post an array to web api or mvc controller and get a file back to download as a result?

I use an html table where it's content can be changed with mouse drag and drop implemented. Technically, you can move the data from any table cell to another. The table size 50 row * 10 column with each cell given a unique identifier. I want to export it to .xlsx format with C# EPPlus library, and give back the exported file to client.
So I need the pass the whole table data upon a button press and post it to either a web api or an mvc controller, create an excel file (like the original html table data) and send it back to download with browser.
So the idea is to create an array which contains each of table cell's value ( of course there should be empty cells in that array), and post that array to controller.
The problem with that approach lies in the download, if I call the api or mvc controller with regular jquery's ajax.post it did not recognize the response as a file.
C# code after ajax post:
[HttpPost]
public IHttpActionResult PostSavedReportExcel([FromBody]List<SavedReports> savedReports, [FromUri] string dateid)
{
//some excel creation code
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StreamContent(new MemoryStream(package.GetAsByteArray()))
};
response.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
{
FileName = dateid + "_report.xlsx"
};
ResponseMessageResult responseMessageResult = ResponseMessage(response);
return responseMessageResult;
}
Usually, for this kind of result I could use window.location = myurltocontroller to download properly , but that is only for GET requests, POST anything is not possible.
I found some answers which could help me in this topic:
JavaScript post request like a form submit
This points out I should go with creating a form, which passes the values, but I do not know how to do so in case of arrays (the table consists 50*10 = 500 values which I have to pass in the form)
I tried some only frontend solutions to the html-excel export problem, which of course does not require to build files on api side, but free jquery add-ins are deprecated, not customizeable, handle only .xls formats, etc.
I found EPPlus nuget package a highly customizeable tool, that is why I want to try this is at first place.
So the question is: how can I post an array of 500 elements, that the controller will recognize, generate the file, and make it automatically download from browser?
If you can provide some code that would be fantastic, but giving me the right direction is also helpful.
Thank you.
You can use fetch() (docs) to send the request from the JS frontend. When the browser (JS) has received the response, it can then offer its binary content as a download. Something like this:
fetch("http://your-api/convert-to-excel", // Send the POST request to the Backend
{
method:"POST",
body: JSON.stringify(
[[1,2],[3,4]] // Here you can put your matrix
)
})
.then(response => response.blob())
.then(blob => {
// Put the response BLOB into a virtual download from JS
if (navigator.appVersion.toString().indexOf('.NET') > 0) {
window.navigator.msSaveBlob(blob, "my-excel-export.xlsx");
} else {
var a = window.document.createElement('a');
a.href = URL.createObjectURL(blob);
a.download = "my-excel-export.xlsx";
a.click();
}});
So the JS part of the browser actually first downloads the file behind the scenes, and only when it's done, it's triggering the "download" from the browsers memory into a file on the HD.
This is a quite common scenario with REST APIs that require bearer token authentication.

Express JS render view with received image

I am working with two Express JS applications one is an API and second is application that is using this API by making requests and displaying received informations to user.
In API route I'm sending image as response:
router.get('/:customer_id',authController.isAuthenticated,(req,res) => {
.
. Retrieving customer data
.
return res.sendFile('/uploads/'+foundCustomer.doc_path);
});
And later another application is getting this document:
router.get('/:customer_id',(req,res) => {
var options = {
url: 'http://'+config.API.user+':'+config.API.password+'#'+config.API.host+':'+config.API.port+'/customers/'+req.params.customer_id
};
request(options,(err,response,body)=>{
return res.render('customer/show',{
document: ?, // Send document as parameter to view
});
});
});
In this point I want to render customer/show(EJS view engine) with customer document, but I don't want to save this document in my application files, because document is only needed to display in view (customer details and document are stored in another application).
I was trying to create temporary directory in my application structure, but it is difficult to manage deleting those not needed documents (Application has many users and at the same time many customers can be displayed).
Another solution that I was trying to implement is to make Ajax request on client side and latter append received document to <object data='document'>. But this request has to be authenticated with user and password, so I realised that storing credentials on client side javascript is not the best idea...
I am not sure that is it even possible to render and display image without saving in application files?
I would be grateful for any help, maybe the best workaround is to somehow manage temporarily saved documents.
Why not create a File object inside EJS template then use that for src attribute on an <img> ? You're already getting the raw buffer/blob from your image API server. Store it inside template.
From https://developer.mozilla.org/en-US/docs/Web/API/Blob/Blob
// place this code (store this variable) inside of your EJS template
// so it can be used by the client-side JS
var aBlob = new Blob( array[, options]); // Where array is the raw buffer data returned from your image API server
See https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL
var objectURL = URL.createObjectURL( aBlob ); // Where object is a Blob object
See https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/srcObject
const img = document.createElement('img');
img.src = objectURL;
Final solution (tested), using axios to make API request:
In my route I'm going to make HTTP request to my API to retrieve PDF file(document):
axios.get(`http://my-api/customer/id`).then(response => {
var photo = new Buffer(response.data, 'binary').toString('base64');
return res.render('customers/show',{
document: document
});
});
In my ejs view, I'm using HTML object tag to display received PDF:
<object data="data:application/pdf;base64,<%-document%>"></object>

How to write to js file at specific location on key value pairs?

I am writing to a js file using protractor as follows :
index.js
var outputFile = '../Actions/data_write.js';
var username = "someusername";
var password = "somepassword";
var fs = require('fs');
var text = "userCredentials : {username : '"+username+"', password : '"+password+"'};";
fs.writeFile(outputFile, text, function(error){
if(error){
console.log(error);
}else{
console.log('data saved to '+outputFile);
}
});
My issue is I am not able to figure out how to write this data at specific location. So like right now the text is written to the entire file by replacing the old content. I want to write it at say at specific location, say I have multiple data with username and password defined in array in this file. I want to write to that specific array.
FileSystem APIs do not provide support for editing a file, rather focus on file operations.
You can read the older content into an object or a string, then navigate through it to figure out the right position for insertion, add your new content, and then write the transformed data back into the file.
If your app involves intensive file content modification with seeking to and fro, you may consider writing a native add-on with memory mapped file, for efficiency and performance.
Hope this helps.

phonegap read and write json file

I am looking to store a JSON file locally on IOS/Android in a Phonegap(Cordova) application.
Basically, I retrieve a JSON file from the server ($.GETJSON) and I want to first store the JSON file and then retrieve and modify it.
I've looked at FileWriter but I don't see a mimetype... the only example gives text files.
Thanks in advance!
Nick
Nick, just use FileWriter.write to save your JSON data to disk. JSON is a text based file anyway so there is no need to set the mime type. When you are ready to load the file again use FileReader.readAsText. In your "onloadend" handler of the FileReader the method will be called with an event and event.target.result will be your JSON data. Then you'll do a
var myJson = JSON.parse(event.target.result);
to turn the text into a JSON object.
(for template or default settings) I just store them in seperate constant files so i don't have to use any special file utility addons or commands, super easy:
(function(){
angular.module('app').constant('settings_json',
{
"name":"settings",
"data":[
{
"set":"globals",
"share_diagnostics":true,
"user_prefs_save_cloud": true
},
{
"set":"user",
"fname":'',
"lname": '',
"telephone": '',
"email": ''
}
]
}
)})();
Then in your app: (after injecting 'settings_json')
var settings = angular.fromJson(settings_json);

Categories