Multiple Image Upload in Angular JS - javascript

My form will have two file input fields and other fields.The user will be sleecting two different types of files and putting in some data. On submit button I want to send both the files along with the accompanying data to the server.
I have come across two Angular File Uploaders
Angular-file-upload (nervgh)
Angular File upload (danial farid)
Both allow multiple files but for each file there is one Http request .But the behaviour I want is 1 Post request that sends two files and some JSON data.
My backend is in NodeJS.

You will want something like this.
$http({
method: 'POST',
url: '/api/fogbugz/bug/create',
data: { request: $scope.request, files: $scope.files },
headers: { 'Content-Type': undefined },
transformRequest: function(data) {
var formData = new FormData();
formData.append("request", angular.toJson(data.request));
for (var i = 0; i < data.files.length; i++) {
formData.append("File" + (i + 1), data.files[i]);
}
formData.append("nFileCount", data.files.length);
return formData;
}
}).success(function(data) {
}).error(function(error, response) {
});
The important part is that you have to set set Content-Type in your header to undefined instead of multipart/form-data because undefined will set the correct boundary for the form data.

Related

Error uploading single json file as input as workitem (DesignAutomation)

I could successfully compile design automation web application with input file, as RVT and Json attached.
But I need to pass only a Json file, as input for workItem. in ForgeDesignAutomation.js, I wrote it as below. But looks like inputfile need to be stringified . Please help me to correct the syntax below.
here 'inputFile' is a Json file, I am not uploading any rvt file, as my addin takes only a json file as input, which is array of strings and return a rfa file as output.
How to stringify 'inputFile', when it is just a .json file ?
function startWorkitem()
{
var inputFileField = document.getElementById('inputFile');
if (inputFileField.files.length === 0) { alert('Please select an input file'); return; }
if ($('#activity').val() === null) { alert('Please select an activity'); return };
var file = inputFileField.files[0];
let activityId = $('#activity').val();
if (activityId == null)
{
alert('Please select an activity'); return
};
if (activityId.toLowerCase() === "myfirst_da4ractivity+dev")
{
startConnection(function () {
var formData = new FormData();
formData.append('inputFile', file);
//file is not uploading-------I think I could not pass the Json file.
//I need to pass connection ID here too.
writeLog('Uploading input file...');
$.ajax({
url: 'api/forge/designautomation/workitems',
dataType: 'json',
data: formData,
processData: false,
contentType: false,
type: 'POST',
success: function (res)
{
writeLog('Workitem started: ' + res.workItemId);
}
});
});
}
}
From your question, you have a client, that submits to your server, which then submits to Forge.
That way, how you submit to api/forge/designautomation/workitems endpoint varies on how it's expecting the data. As you have a .json file, you don't need to stringfy is, it's passed as a file. If you decide to send it as data, then stringfy and adjust to data: { your JSON data here },
Assuming the file came from your client to your server, you can then submit that JSON file to Forge as an input for your Workitem.

CakePHP3 ~ CSRF-token mismatch on second function

I am currently developing an JavaScript reliable system that works with the CakePHP 3 framework as the back-end. All the actions in my panel are executed on the same page / url, it is a one-page-application. Currently I got a bunch of functions working and decided it was time to investigate the CSRF-component of CakePHP 3. When I enabled it I got the 400 error which indicated that no CSRF-token was given. After a lot of research I came to the solution that this is fixed with the FormMaker or with manually implementing the token in my JQuery ajax request. This worked so I decided to also implement it the next function. But as you may guess, this did not work. The second ajax request gives a CSRF-token mismatch. Please look at my code below:
My first request that actually works:
function getSectionData(controller, method = null) {
fetch("<?=$this->Url->build(['controller' => '']);?>" + "/" + controller + "/getSectionData", {
method: 'POST',
headers: {
"Content-Type": "application/json",
"X-CSRF-Token": <?= json_encode($this->request->param('_csrfToken')); ?>
},
body: JSON.stringify({
method: method
})
})
.then((res) =>
res.json())
.then((data) => {
console.warn(data);
let response = data.response;
if (response.success == 1) {
// Action to do when data has been received
let method = response.method;
let rows = response.rows;
window[method](controller, rows);
} else if (response.success == 0) {
// Message when an error occures
}
})
.catch((err) => console.log(err))
}
Eventually the second function gets activated after less than a second:
function renderElement(element, id, data = null) {
let path = "<?= $this->request->here; ?>" + "/renderElement/" + element;
$('#' + id).load(path, {
data: data,
headers: {
"X-CSRF-Token": <?= json_encode($this->request->param('_csrfToken')); ?>
}
});
}
In this function I load a preset HTML element from another file which can contain data-elements, that is why it first requests data from the controller. I use the same headers as in the first function and the CSRF-token is present in the console. But it does not work and throws the mismatch error. I would like to know why it gives this error and how I can solve it, like, do I have to refresh it and how?
Note that I am using a version of CakePHP 3 before the 3.6 update which removed the CSRF component and added the CRSF middleware.
Thanks in advance.
The jQuery.load() function doesn't accept AJAX configuration parameters, the second argument is either a callback, or an object that defines the POST data to submit alongside the request.
You'll either have to switch to using a configurable AJAX request (for example as in your first snippet), or globally configure jQuery to set the required header for all AJAX requests:
$.ajaxSetup({
headers: {
'X-CSRF-Token': <?= json_encode($this->request->param('_csrfToken')); ?>
}
});
See also
https://api.jquery.com/load/
https://api.jquery.com/jQuery.ajaxSetup/

Amazon S3 Copy and Rename file using REST API in Javascript/AJAX/JQuery

I have a requirement to copy and rename some S3 media files (they will remain in the same bucket) upon request in my Javascript application. I believe the best way to this is to use the PUT Object - Copy described here:
http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectCOPY.html
My question arises in how to construct the actual Ajax call to have this happen. I know how to specify the target file bucket and file name (such as "x-amz-copy-source": "EXAMPLE_BUCKET/example.png") but how do I specify the source bucket and file name?
Is it part of the FormData, is it built into the url or does the key somehow represent it? Yes, I am new to S3 so forgive my lack of knowledge.
Here is what I have so far (I have not executed this but will later today):
copyAndRename: function (url, newBucketAndFile, key, contentType, accessKey, region, policy, signature) {
var fd = new FormData();
var date = moment().utc().format("YYYYMMDD");
fd.append("key", key); // Not sure if needed?
fd.append("Content-Type", contentType);
fd.append("x-amz-copy-source", newBucketAndFile);
fd.append("acl", "private");
fd.append("policy", policy);
fd.append("x-amz-meta-tag", "");
fd.append("x-amz-meta-uuid", "11111111111111");
fd.append("x-amz-server-side-encryption", "AES256");
fd.append("X-Amz-Credential", accessKey + "/" + date + "/" + region + "/s3/aws4_request");
fd.append("X-Amz-Date", date + "T000000Z");
fd.append("X-Amz-Algorithm", "AWS4-HMAC-SHA256");
fd.append("X-Amz-Signature", signature);
var success = false;
$.ajax({
url: url, // Is this the bucket and file path?
method: "PUT",
data: fd,
processData: false,
contentType: false,
async: false
}).done(function (result) {
success = true;
}).fail(function (error) {
console.log("error", error);
success = false;
});
return success;
}

C# web api / Javascript file upload set filename

I use asp.net web api for backend and a javascript client.
I use the form input to let the user select a file, and then I make an ajax request to the web api with the FormData, something like this:
var form = $('#uploadForm')[0];
var formData = new FormData(form);
$.ajax({
...
type: 'POST',
data: formData,
...
});
On the backend I receive this request, and get the data from the HttpContent object. Something like this:
try
{
if (!Request.Content.IsMimeMultipartContent("form-data"))
{
return StatusCode(HttpStatusCode.UnsupportedMediaType);
}
var result = await _blobRepository.UploadBlobs(Request.Content);
if (result != null && result.Count > 0)
{
return Ok(result);
}
return BadRequest();
}
I need to have unique file names.
How can I rename the file?
It does not matter if it is the client side, or the backend.

Can't create and pass jsonp data

I am new to Node.js and I have created a method that should asynchronously fetch jsonp data via ajax and display the retrieved content in a graph. This method works fine when the url points to a static js file (in this case productsData.js) containing jsonp data:
function loadChart(destElementId, alertId) {
$.ajax({
url:'http://localhost:3000/products/data/productsData.js',
type: "GET",
data: {prodId: prodId},
jsonp: true,
dataType : 'json',
jsonpCallback: "jsonpCallback"
});
window["jsonpCallback"] = function(data) {
populateData(data, destId);
}
}
As in normal applications, I want to pass real data fetched via an external web service. I have created the following js file (data-client.js) that retrieves data from a specific web service. When calls are browser-based, the data is fetched successfully as a normal json and is displayed accordingly in the browser.
var express = require('express');
var router = express.Router();
var http = require('http');
var yaml_config = require('node-yaml-config');
var config = yaml_config.load(__dirname + '/../config/app-config.yml');
router.get('/data/:id', function (req, res, next) {
var opts = {
host: config.alertService.host,
port: config.alertService.port,
method: 'GET',
path: '/DataService/rest/receiveData/' + req.params.id
}
var reqGet = http.request(opts, function (dataResponse) {
var responseString = '';
dataResponse.on('data', function (data) {
responseString += data;
});
var response = {x:[],y:[],z:[],t:[]};
dataResponse.on('end', function () {
var responseObject = JSON.parse(responseString);
var accs = responseObject.data.listPCS;
for(var i in accs){
response.x.push(accs[i].accX);
response.z.push(accs[i].accY);
response.y.push(accs[i].accZ);
response.t.push(accs[i].timestamp);
}
res.json(response);
});
});
reqGet.end();
reqGet.on('error', function (e) {
console.error(e);
});
});
module.exports = router;
The first step for using live jsonp data is to replace the previous url value with:
url: 'http://localhost:3000/products/data/'+productId,
The second step is to replace in the data-client.js:
res.json(response);
with:
res.jsonp('jsonpCallback('+ JSON.stringify(response) + ');');
Somehow the data is not fetched. When I try to get the data via the browser (i.e. by entering http://localhost:3000/data/ID937) however I get the following result:
"jsonpCallback({\"x\":[1,1,1],\"y\":[2,1,4],\"z\":[0,0,9],\"t\":[1462790772000,1462790772010,1462790772020]});"
Can someone please tell me where the problem may be? I would be very thankful.
It looks like you are using Express.
jsonp() expects to be passed your raw data, not a string containing the complete response. It also expects to read the callback name from the query string, which jQuery will generate for you if you let it.
So the first thing to do is to fix your client side code so it passes the callback name correctly
On the client
$.ajax({
url: 'http://localhost:3000/products/data/' + productId,
dataType: 'jsonp',
}).done(function(data) {
populateData(data, destId);
});
The changes here are:
GET is the default (and, for JSONP, only option) so there is no need to specify the type.
You are passing the data as a URL path part, not a query string. Drop the data property that you aren't using.
The jsonp property is used to override the callback name. That's harmful, don't do that (likewise, don't specify jsonpCallback). jQuery will generate one for you and add it to the query string.
If you are dealing in JSONP then specify that as the data type, not JSON.
Don't create your own global manually. Pass your function to done and let jQuery make it a global (with a generated name to match the callback).
On the server
Just pass the data structure you want to send back to jsonp().
res.jsonp(response);
The callback name will be read from the query string by Express.

Categories

Resources