File upload Angular 8 with application/octet-stream - Binary - javascript

I have an api that expects to receive an image with "application/octet-stream", I currently have a "ng2-file-upload" library, I would like to make it work with it but if it is not possible I could try with another one or just Even angular.
Currently my code looks like this:
constructor(
) {
const bearer = 'Bearer ' + this.authService.getToken();
this.uploadImageNewsletter = new FileUploader({
url: `https://myapi/upload?extension=jpg`,
autoUpload: true,
method: 'post',
isHTML5: true,
allowedMimeType: ['application/octet-stream', 'image/png', 'image/jpg', 'image/jpeg', 'image/gif'],
allowedFileType: ['application/octet-stream', 'image', 'pdf'],
// disableMultipart: false,
headers: [
{
name: 'Authorization',
value: bearer
},
{
name: 'Content-Type',
value: 'application/octet-stream'
}
]
});
this.uploadImageNewsletter.onProgressAll = () => {
this.loading = true;
};
this.uploadImageNewsletter.onCompleteItem = (item: FileItem) => {
item.remove();
this.loading = false;
};
}
With postman I can upload with the following settings:

Related

Error when using fetch method and NodeJs route [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 days ago.
Improve this question
I got an issue using fetch method in JavaScript with a NodeJS routing.
My JS code :
fetch(url, {
method: 'POST',
headers: {
'Accept': 'application/json, text/plain, */*',
'Content-Type': 'application/json'
},
credentials: 'same-origin',
body: JSON.stringify({ ids: arrayIds })
}).then(function(response) {
return response.json();
}).then(function(data) {
if (data.reload) {
document.location.reload();
} else if (data.url) {
document.location.href = data.url;
}
});
My NodeJS route :
function _postMultiplePrint(request, response) {
var fonts = {
Roboto: {
normal: 'public/fonts/OpenSans-Regular.ttf',
bold: 'public/fonts/OpenSans-Bold.ttf',
italics: 'public/fonts/OpenSans-Italic.ttf',
bolditalics: 'public/fonts/OpenSans-BoldItalic.ttf'
}
},
printer = new PdfPrinter(fonts),
docDefinition, pdfDoc;
docDefinition = {
content: [
{
text: 'This paragraph fills full width, as th'
}
],
pageSize: 'A4',
pageMargins: [72, 72],
footer: {},
background: {}
};
pdfDoc = printer.createPdfKitDocument(docDefinition);
response.setHeader('Content-type', 'application/pdf');
response.setHeader('Content-disposition', 'inline; filename="book.pdf"');
pdfDoc.pipe(response);
pdfDoc.end();
response.send(JSON.stringify({ reload: false, url: '' }));
}
My issue : my book.pdf is not loaded in the page when I'm not using fs to write it.
It works with this code but I write files on the server and I don't want to do that :
function _postMultiplePrint(request, response) {
var fonts = {
Roboto: {
normal: 'public/fonts/OpenSans-Regular.ttf',
bold: 'public/fonts/OpenSans-Bold.ttf',
italics: 'public/fonts/OpenSans-Italic.ttf',
bolditalics: 'public/fonts/OpenSans-BoldItalic.ttf'
}
},
printer = new PdfPrinter(fonts),
docDefinition, pdfDoc;
docDefinition = {
content: [
{
text: 'This paragraph fills full width, as th'
}
],
pageSize: 'A4',
pageMargins: [72, 72],
footer: {},
background: {}
};
pdfDoc = printer.createPdfKitDocument(docDefinition);
pdfDoc.pipe(fs.createWriteStream('./public/uploads/book.pdf'));
pdfDoc.end();
response.send(JSON.stringify({ url: '/uploads/book.pdf' }));
}
Each HTTP request can have one and only one response.
Your JS makes an HTTP request. Your server-side code then tries to response with PDF (response.setHeader('Content-type', 'application/pdf'); response.setHeader('Content-disposition', 'inline; filename="book.pdf"'); pdfDoc.pipe(response); pdfDoc.end();) and JSON (response.send(JSON.stringify({ reload: false, url: '' }));).
That's two responses. That won't work.
What's more, the Content-disposition will be ignored because it is a request initiated by Ajax, not by regular browser navigation.
The first backend code is fine, it's just not compatible with the frontend. Here's a full working example
backend
pdfDoc = printer.createPdfKitDocument(docDefinition);
response.setHeader('Content-type', 'application/pdf');
response.setHeader('Content-disposition', 'inline; filename="book.pdf"');
pdfDoc.pipe(response);
pdfDoc.end();
// The below code must be remove
// since the response has been sent by pdfDoc.pipe(response);
// response.send(JSON.stringify({ reload: false, url: '' })); // <- remove this line
Frontend if your route is POST method
const form = document.createElement("form");
// Define your route here
form.setAttribute("action", "http://localhost:8000");
form.setAttribute("method", "POST");
const btn = document.createElement("button");
btn.setAttribute("type", "submit");
form.appendChild(btn);
document.body.appendChild(form);
btn.click();
Frontend if your route is GET method
window.open("http://localhost:8000");

How to fetch Sleep data from Google's REST api?

I'm trying to fetch my sleep data from Google-Fit.
When I make the following request -
const { data: sleepData } = await axios({
method: 'POST',
url: 'https://www.googleapis.com/fitness/v1/users/me/dataset:aggregate',
headers: {
Authorization: `Bearer ${accessToken}`,
},
data: {
aggregateBy: [{ dataTypeName: 'com.google.sleep.segment' }],
bucketByTime: { durationMillis: 86400000 },
startTimeMillis: startTimeQuery, // day start time in UNIX
endTimeMillis: endTimeQuery, // day end time in UNIX
},
});
I'm getting the following data with empty points -
{
"bucket": [
{
"startTimeMillis": "1651115600000",
"endTimeMillis": "1651202000000",
"dataset": [
{
"dataSourceId": "derived:com.google.sleep.segment:com.google.android.gms:merged",
"point": []
}
]
},
{
"startTimeMillis": "1651202000000",
"endTimeMillis": "1651288400000",
"dataset": [
{
"dataSourceId": "derived:com.google.sleep.segment:com.google.android.gms:merged",
"point": []
}
]
},
]}
Has anyone run into similar problems?
I'm using Google-Fit on an Android Device.
Hey here is a working example from Google Fitness REST API with my account which is connected to my sleep tracking device.
var axios = require('axios');
var data = JSON.stringify({
"aggregateBy": [
{
"dataTypeName": "com.google.sleep.segment"
}
],
"endTimeMillis": {endTimeMillis},
"startTimeMillis": {startTimeMillis}
});
var config = {
method: 'post',
url: 'https://www.googleapis.com/fitness/v1/users/me/dataset:aggregate',
headers: {
'Authorization': 'Bearer {AccessToken}',
'Content-Type': 'application/json'
},
data : data
};
axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
The Only difference is to remove the bucketByTime so that Fitness API will send the segment points as small as possible.

how to add cloudinary parameters to upload plugin in Trumbowyg

I am using the trumbowyg editor in my project. From the documentation, I know that I can use the following code to set the image upload content of the editor.
$('#editor')
.trumbowyg({
btns: ['upload'],
plugins: {
// Add imagur parameters to upload plugin for demo purposes
upload: {
serverPath: 'https://api.imgur.com/3/image',
fileFieldName: 'image',
headers: {
'Authorization': 'Client-ID xxxxxxxxxxxx'
},
urlPropertyName: 'data.link'
}
}
});
this works fine with imgur but I want to use cloudinary server instead of imgur.
could anyone please guide what I have to do with plugins:{} when using cloudinary?
also I'm using dropzone.js with cloudinary to upload image and this is also working properly.
here is dropzone function code:
Dropzone.autoDiscover = true;
var myDropzone = new Dropzone(document.getElementById('image-upload'), {
clickable: "#image-upload #btn-add",
uploadMultiple: false,
autoProcessQueue: true,
acceptedFiles:'.jpg,.png,.jpeg,.gif',
parallelUploads: 10,
maxFilesize: 9,
maxFiles: 10,
url: 'https://api.cloudinary.com/v1_1/demo_project/image/upload',
addedfile: function(file) {
// console.log(file);
new Noty({
type: 'success',
text: "Uploading...",
timeout: false
}).show();
// myDropzone.processQueue();
},
success: function(file, response){
new Noty({
type: 'success',
text: "Uploaded!",
killer: true
}).show();
newImageArray.push({
public_id: response.public_id,
url: response.url,
secure_url: response.secure_url
});
newImageArrayJSON = JSON.stringify(newImageArray);
$imageStorage.val(newImageArrayJSON)
$("#image-upload .image").html('<img src="' + response.secure_url + '">')
$("#image-upload #btn-add").hide();
$("#image-upload #btn-remove").show();
}
});
myDropzone.on('sending', function (file, xhr, formData) {
formData.append('api_key', 112233445566778);
formData.append('timestamp', Date.now() / 1000 | 0);
formData.append('upload_preset', 'mypreset');
});
Thanks in advance!
I would advise starting with the following basic implementation which I tested and worked for me:
$('#editor').trumbowyg({
btns: ['upload'],
plugins: {
upload: {
serverPath: 'https://api.cloudinary.com/v1_1/demo_project/image/upload',
fileFieldName: 'file',
urlPropertyName: 'data.secure_url',
data: [
{name: 'api_key', value: '112233445566778'},
{name: 'timestamp', value: Date.now() / 1000 | 0},
{name: 'upload_preset', value: 'mypreset'}
],
success: function (data) {
console.log(data);
},
error: function (error) {
console.log(error.responseText);
}
}
}
});
You can log in to your Cloudinary account and modify your upload preset to restrict uploads based on different conditions, the same as you do with dropzone.js, for example to only allow uploads of specific formats etc.

extjs store sometimes calling create instead of update

We have the following store in ExtJS 4.2:
Ext.define('Example.store.BasketDocuments', {
extend: 'Ext.data.Store',
model: 'Example.model.Document',
autoLoad: true,
autoSync: true,
sorters: [
{
property: 'doc_type',
direction: 'ASC'
}
],
proxy: {
type: 'rest',
url: baseUrl + 'document_basket',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json;charset=utf-8'
},
reader: {
type: 'json',
root: 'items'
},
writer: {
type: 'json'
},
actionMethods: {create: "POST", read: "GET", update: "PUT", destroy: "DELETE"}
}
});
It is attached to a grid with drag and drop functionality.
When we drag around 10 files (for 9 it works) to the grid which would immediately update the store, we get a server error, because we do not implement the POST function for URLs like
/api/document_basket/1964?_dc=1459498608890&{}
This is only for one entry.
For the others it would be
/api/document_basket?_dc=1459498608941&{}
which works.
Dragging only that single entry works.
So ExtJS is sending a POST request with an ID in the URL, which should be a PUT instead? Why is that?
I was able to fix this in my project.
Reason was that I was adding items to the store in a loop - so after each add of - let's say 14 files - a sync was done.
I discovered that there were 105 requests, which is just 1+2+3+4+5+6+7+8+9+10+11+12+13+14 so this caused a race condition.
Solution is to disable syncing before the loop:
onBeforeDropItem: function (node, data, overModel, dropPosition, dropHandlers, eOpts) {
dropHandlers.cancelDrop();
var store = Ext.getStore('BasketDocuments');
store.suspendAutoSync(); // new
if (node.id != 'documenttreepanel-body') {
Ext.Array.each(data.records, function (r, index) {
r = r.copy();
r.phantom = true;
r.data.id = null;
r.data.download_size = 1;
r.data.download_type = 1;
if (r.data.doc_type == 1) {
if (r.data.count == 0) {
Ext.create('Ext.window.MessageBox').show({
title: Ext.ux.Translate.get('Info'),
msg: Ext.ux.Translate.get('Ordner') + '<b>' + r.data.name + '</b>' + Ext.ux.Translate.get(' Is empty and cannot be added ') + '.',
buttons: Ext.Msg.OK,
modal: true
});
} else {
store.add(r);
}
} else {
store.add(r);
}
});
}
store.sync(); // new
store.resumeAutoSync(); // new

Using Facebook's Mobile Hosting API with Parse Cloud Code for App Links

I am having trouble getting App Links working with Parse.
Since my App is mobile only i wanted to use Facebook's Mobile Hosting API.
And since you need to send your Facebook App Secret with the request i wanted to do it with Parse Cloud Code.
All i coud find on the Facebook documentation was how to do it with cURL:
curl https://graph.facebook.com/app/app_link_hosts \
-F access_token="APP_ACCESS_TOKEN" \
-F name="iOS App Link Object Example" \
-F ios=' [
{
"url" : "sharesample://story/1234",
"app_store_id" : 12345,
"app_name" : "ShareSample",
}, ]' \
-F web=' {
"should_fallback" : false, }'
so this is what i came up with in cloud code
Parse.Cloud.httpRequest({
method: 'POST',
url: 'https://graph.facebook.com/app/app_link_hosts',
headers: {
'Content-Type': 'multipart/form-data'
},
body: {
access_token : "APP_ACCESS_TOKEN",
name : "iOS App Link Object Example",
ios : '[{"url" : "sharesample://story/1234","app_store_id" : 12345,"app_name" : "ShareSample",},]',
web : '{"should_fallback" : false,}'
}
the response i get is: Request failed with response code 400
now i just read that multipart/form-data is not supported withParse.Cloud.httpRequest
so is there another way to do this?
update: just found out that you can send multipart data with a Buffer,
so this is my code now
var Buffer = require('buffer').Buffer;
var access_token = new Buffer('APP_ACCESS_TOKEN','utf8');
var name = new Buffer('iOS App Link Object Example','utf8');
var ios = new Buffer('[{"url" : "sharesample://story/1234","app_store_id" : 12345,"app_name" : "ShareSample",},]','utf8');
var web = new Buffer('{"should_fallback" : false,}','utf8');
var contentBuffer = Buffer.concat([access_token, name, ios, web]);
Parse.Cloud.httpRequest({
url: 'https://graph.facebook.com/app/app_link_hosts',
method: 'POST',
headers: {
'Content-Type': 'text/html; charset=utf-8'
},
body: contentBuffer
}
however i am still getting the same result :(
update2: got it working with content type application/x-www-form-urlencoded and normal body. But i think the error was somewhere in my parameters since i tested it with curl and got the same response
It took me a few hours, but I finally got it working:
// Returns the canonical url, like https://fb.me/....
Parse.Cloud.define("createAppLink", function(request, response) {
// see https://developers.facebook.com/docs/graph-api/reference/v2.5/app/app_link_hosts
var storyId = request.params.storyId + ''; // param identifying a single "post"
var appId = 'APP_ID';
var appSec = 'APP_SECRET';
var appToken = appId + '|' + appSec; // your app token
Parse.Cloud.httpRequest({
url: 'https://graph.facebook.com/app/app_link_hosts',
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ // you need to stringify it
access_token: appToken,
name: 'LINK TO ' + storyId, // it is needed but not public
android: [{
url: 'app://story/' + storyId, // deep link url
package: 'com.package', // your package name
app_name: 'APP' // your app name
}],
web: { should_fallback: 'false' }
})
}).then(function(httpResponse) {
// We get an id, by which we can fetch
// the canonical url with a get request
var data = JSON.parse(httpResponse.text);
var id = data.id;
return Parse.Cloud.httpRequest({
url: 'https://graph.facebook.com/' + id,
method: 'GET',
headers: {
'Content-Type': 'application/json'
},
params: {
access_token: appToken,
fields: 'canonical_url',
pretty: 'true'
}
});
}).then(function(httpResponse) {
var data = JSON.parse(httpResponse.text);
var canonicalUrl = data.canonical_url;
response.success(canonicalUrl);
}, function(error) {
response.error(error);
})
});

Categories

Resources