Sencha ExtJS 7 - How to handle Blob, File, FormData instance object - upload

How can i send to server a Blob, File and FormData Instance Object using these two way Ext.Ajax.request and Ext.form.Panel.submit?
var blob = new Blob(chunks, {type: chunks[0].type});
var file = new File(["lorem.."], "test.txt", {type: "text/plain"});
var formData = new FormData();
formData.append("text", file);
formData.append("video", blob, "video.webm");
How to add "formData" or simple "blob" and/or "file" into Ext.Ajax.request(options) and Ext.form.Panel.submit(options)?
Another doubt: How to set "file" into value of "filefield" component?
Thanks!

Something in the line of this might work:
Ext.Ajax.request({url: 'https://some.url.com', method: 'POST', rawData: formData, contentType: false})
You can check out this thread as well.

Related

how to save a blob file using carrierwave in rails

So i have a requirement where i record a video and save it in the database, the recording of the video is working fine, only thing is it generates a blob file, then i use js to send the blob file to the server. This are my params
{"testqwe"=>{"attr"=>"blob:http://localhost:3000/6f12f123-b1d0-7bfc-6b15-d3b54341946"}, "controller"=>"myControler", "action"=>"test"}
i have an uploader in place , but it does not save anything.
so how can i save this using carierwave to my database?
here is my javascript
mediaRecorder.onstop = (ev) ->
blob = new Blob(chunks, 'type': 'video/mp4;')
chunks = []
videoURL = window.URL.createObjectURL(blob)
vidSave.src = videoURL
$.ajax
type: 'POST'
content_type: "video/webm"
url: '/test'
enctype: "multipart/form-data"
data: testqwe: attr: videoURL
return
any one still trying to figure out this, u can refer this link
How to pass blob url to rails create method by ajax
mediaRecorder.onstop = (ev) ->
blob = new Blob(chunks, 'type': 'video/mp4;')
chunks = []
videoURL = window.URL.createObjectURL(blob)
vidSave.src = videoURL
formData = new FormData
formData.append('testqwe[attr]', blob);
$.ajax
type: 'POST'
url: '/test'
processData: false
contentType: false
data: formData
return
Send and save the audio/video data as a file

Encoding issue with Axios

I am fetching a web page with axios, but the content-type of the response is ISO-8859-1, and the result given by axios seems like it parses it as UTF-8 and the result has corrupt characters.
I tried to convert the result encoding but nothing works, and I think it does not because of this
For example in the got library I can set encoding to null and overcome the problem, but I would like to ask you what can I do with axios to disable the auto-encoding or change it?
My approach was this:
Make the request with responseType and responseEncoding set as below
const response = await axios.request({
method: 'GET',
url: 'https://www.example.com',
responseType: 'arraybuffer',
responseEncoding: 'binary'
});
Decode reponse.data to the desired format
let html = iso88592.decode(response.data.toString('binary'));
Note: In my case, I needed to decode it using this package.
Without using interceptor or another package, I got the response on a buffer with:
notifications = await axios.request({
method: 'GET',
url: Link,
responseType: 'arraybuffer',
reponseEncoding: 'binary'
});
And next converting it with:
let html = notifications.data.toString('latin1');
In this github issue Matt Zabriskie recommends using an axios response interceptor, which I think is the cleanest option.
axios.interceptors.response.use(response => {
let ctype = response.headers["content-type"];
if (ctype.includes("charset=ISO-8859-1")) {
response.data = iconv.decode(response.data, 'ISO-8859-1');
}
return response;
})
const notifications = await axios.request({
method: 'GET',
url: 'https://...your link',
responseType: 'arraybuffer',
reponseEncoding: 'binary'
});
const decoder = new TextDecoder('ISO-8859-1');
let html = decoder.decode(notifications.data)

ember file upload to rails, encoding and decoding with base64

I'm almost there, but I'm having an issue with decoding of the file. When decoding the file is not correct.
The code that I use to upload the file:
createDataSet: function() {
var data = new FormData();
data.append('original_filename', this.get('fileName'));
data.append('datafile', this.get('newData'));
data.append('project_id', this.get('content.id'));
data.append('name', this.get('content.name'));
$.ajax({
url: '/data_sets.json',
data: data,
cache: false,
contentType: false,
processData: false,
dataType: 'json',
type: 'POST',
success: function(data) {
alert('ok');
},
error: function(xhr, data, errorThrown) {
alert('error');
}
});
}
On the Rails side I'm trying to pick this up with the following method:
def create
# take care of the attachement
datasetfilename = Pathname.new(params[:original_filename]).basename
newfile = File.open(datasetfilename, 'w') do |f|
f.write(Base64.decode64(params[:datafile]))
end
#dataset = DataSet.new
#active_data_set = #dataset.active_data_sets.build
#active_data_set.project_id = params[:project_id]
#active_data_set.save
#dataset.name = params[:name]
#dataset.filename = datasetfilename
#dataset.tempfilename = #dataset.savefile newfile
#dataset.save
end
If I use File.open(datasetfilename, 'w') I get an error like this one Encoding::UndefinedConversionError - "\xAB" from ASCII-8BIT to UTF-8. On the other hand, if I open with 'wb' the resulting file is mingled and can't be read.
I already added the meta tag for the file encoding <meta charset="utf-8" /> but without any difference.
If anybody has any hint that would be appreciated.
Just got this working in one of my own controllers, there are 2 main issues:
1) to resolve the encoding issue, use "w:binary" as the write flag instead of "w" (defaults to ASCII)
2) the :datafile params includes some header info "data:text/csv;base64,SUR4CUluZ...", I'm currently splitting on "," but might be better served to decode everything beyond "base64," as I'm not sure if additional commas are allowed.
My working code (slightly different parameter names):
if params.key?(:img_file)
header, data = params[:img_file].split(',')
img_type = header.match(/image\/([a-z]{1,11});/)[1]
file_path = "imgtodo/fund_#{#fund.id}.#{img_type}"
File.open(Rails.root.join('public',file_path).to_s, 'w:binary') do |f|
f.write(Base64.decode64(data))
end
end

fetchEntityByKey not making any requests to the server

I'm trying to create a filemanager using Angularjs and I recently discovered Breezejs and was interested in trying to use it to communicate with my backend and manage my model relations. The backend is a rest api over which I have full control.
I am however running into a problem. I know the id of the file, so I would like to make a request to url of the form backend_url/files/:fileId where :fileId is the url of the file base64 encoded. According to the documentation I should use EntityManager.fetchEntityByKey() for this purpose. This is the function that i use to create the Angularjs service:
var FilestoreService = function () {
var dataService, manager;
dataService = new breeze.DataService({
serviceName: "../VFS-Symfony-Backend/web/app_dev.php/filesystems/local/",
hasServerMetadata: false
});
manager = new breeze.EntityManager({
dataService: dataService
});
manager.metadataStore.addEntityType(fileEntityType);
return {
findOneById: function (id) {
/* I have tried to leave the 3th argument empty or changing it to false with the same results */
return manager.fetchEntityByKey("File", id, true).then(function(){console.log("success");}).fail(function(){console.log("failure");});
/* I have also tried the following approach with the same result:
var type, key, query;
type = manager.metadataStore.getEntityType("File");
key = new breeze.EntityKey(type, id);
query = breeze.EntityQuery.fromEntityKey(key);
return manager.executeQuery(query);
*/
}
};
};
where fileEntityType is defined as:
var FileEntityType = new breeze.EntityType({
shortName: "File"
});
FileEntityType.addProperty(new breeze.DataProperty({
name: "uri",
dataType: breeze.DataType.String,
isNullable: false
}));
FileEntityType.addProperty(new breeze.DataProperty({
name: "mTime",
dataType: breeze.DataType.Int16,
isNullable: false
}));
FileEntityType.addProperty(new breeze.DataProperty({
name: "type",
dataType: breeze.DataType.String,
isNullable: false
}));
FileEntityType.addProperty(new breeze.DataProperty({
name: "size",
dataType: breeze.DataType.int16,
isNullable: true
}));
However, when I call findOneById no request is made to the server and 2 lines are logged to the console:
Should be empty:[] by q.js
failure (as per the fail() callback function)
A 'normal' query (manager.executeQuery(new breeze.EntityQuery().from("Files"));) does result in a request to the server as expected.
I am really quite lost here. I have searched for a solution all weekend and finaly decided to post on SO hoping someone might be able to help me.
Thanks very much for reading.
At least one problem is that you haven't identified the key ('id'?) in your metadata description of the "File" entity type. You have defined every other property except the 'id' property.
You know this but let me tell other readers of this question who may not understand that you are defining the metadata on the JS client rather than retrieving it from the server.
I'm also curious why you are using int16? Is that really the right type? Do you really need to shave off the two bytes?
Finally, Breeze's fetchEntityByKey won't make a request URL in the form "backend_url/files /:fileId". Instead, the request URL will be "backend_url/files /?id=:fileId" as befits an OData query. See the network traffic for Id queries in the queryTests.cs of the DocCode sample.
You can still get that file if the server expects the URL you specified. You won't be using the Breeze query syntax. You'll just hit the service with the URL it expects, e.g.,
function findOne(id) {
// check cache first
var file = manager.getEntityByKey('File', id);
if (file) {
console.log("got it from cache");
return Q(file); // got it; return in resolved promise
}
// not in cache; get from server
return breeze.EntityQuery
.from('Files/'+id) // constructs the URL you want
.using(manager).execute()
.then(function(data){
console.log("success");}
// return the file in a resolved promise
return data.results[0] || null;
})
.fail(function(error){
console.log("failure: "+ error.message);
});
}
This is a variation on the getByIdCacheOrRemote method in queryTest.cs in the DocCode sample.
Yes, it's longer. You're reimplementing fetchEntityByKey so you can hit the remote service the way it expects.
The method begins by looking for the file in cache. The getEntityByKey is a synchronous search of the cache. The findOne method has async syntax ... returns a promise ... because it might have to go to the server. So if we find the file in cache (synchronously), we wrap the result in a resolved Q.js promise for the benefit of the caller which is expecting findOne to be asynchronous.
If the file is not found in cache, you go to the server with a "query" that is really just a request on the URL of your choice.
I haven't tried this a long time. I'm sure you'll tell me if it works ... or does not. If it doesn't, it should and we'll fix it so it does.
As Ward suggested the EnityType I created did need one of its field to be marked as the key field. Besides that the EntityType also needs to have a defaultResourceName to be supplied to its constructor. I think this explains why the 'normal' query did work (the resourceName is supplied by from()) and why fetchEntityByKey did not work. The updated FileEntityType now looks like this:
var FileEntityType = new breeze.EntityType({
shortName: "File",
defaultResourceName: "files"
});
FileEntityType.addProperty(new breeze.DataProperty({
name: "id",
dataType: breeze.DataType.String,
isNullable: false,
isPartOfKey: true
}));
// These properties were not altered
FileEntityType.addProperty(new breeze.DataProperty({
name: "uri",
dataType: breeze.DataType.String,
isNullable: false
}));
FileEntityType.addProperty(new breeze.DataProperty({
name: "mTime",
dataType: breeze.DataType.Int16,
isNullable: false
}));
FileEntityType.addProperty(new breeze.DataProperty({
name: "type",
dataType: breeze.DataType.String,
isNullable: false
}));
FileEntityType.addProperty(new breeze.DataProperty({
name: "size",
dataType: breeze.DataType.int16,
isNullable: true
}));

Loop through html tables data and submit back to server

I have spent the last couple of hours battling to write some javascript and jquery.
Basically I am trying to loop through a table checking if an attribute exists within a TD if it does add its info into an array and post it back to the server
My code (I am sure it could be better)
$("#save-changes").click(function () {
var param = [];
var table = $("#products-grid > .t-grid-content > table tbody tr").each(function (i) {
//find checkboxes using class
var td = ($(this).find("td:nth-child(2)").find(".cb"));
var attr = $(td).attr('data-item');
if (typeof attr !== 'undefined' && attr !== false) {
console.log(td);
param.push({ "itemId": attr, "productId": td.val() });
}
});
console.log(param);
$.ajax({
url: '#Url.Action("ApplyProduct")',
data: param,
type: 'POST',
success: function (e) {
I am now stuck on trying to pass the array back to the server. What do I need to do to send the data back to the server as a parameter the server can understand?
Any help would be great!
add two parameters
dataType: "json",
data: JSON.stringify(param)
to your .ajax call.
Crate an object server side which has two int properties int called itemId and productId and then create a JsonResult route that takes an array of your object that you post too (this would be ApplyProduct in your case).
you cannot send arrays to a server , they have to be strings.
you could join the array together like this
param.join(";");
that would create a string with each value seperated by a ;
also you need to specify the data option as a key-value json
$.ajax({
url: '#Url.Action("ApplyProduct")',
data: {
param : param
},
type: 'POST',
then on the serverside you can split the string back into an array
$param = explode(";",$_POST['param']);

Resources