I want to post multipart form data, for this, we can do like this:
let formData = new FormData()
formData.append('myfile', 'your blob')
this.http.post(url, formData)
But I don't know how to convert a camera image to the blob. I am using native camera plugin and here my code:
cameraOptions: CameraOptions = {
quality: 20,
destinationType: this.camera.DestinationType.DATA_URL,
encodingType: this.camera.EncodingType.JPEG,
mediaType: this.camera.MediaType.PICTURE,
sourceType: this.camera.PictureSourceType.PHOTOLIBRARY
}
constructor(public camera: Camera){}
takePhoto() {
return new Promise(resolve => {
this.camera.getPicture(this.cameraOptions).then((imageData) => {
resolve(imageData);
}, (err) => {
resolve(err);
});
});
}
I tried this code for blob:
dataURLtoBlob(dataURL) {
debugger;
// convert base64/URLEncoded data component to raw binary data held in a string
let byteString: string;
if (dataURL.split(',')[0].indexOf('base64') >= 0) {
byteString = atob(dataURL.split(',')[1]);
} else {
byteString = unescape(dataURL.split(',')[1]);
}
// separate out the mime component
let mimeString = dataURL
.split(',')[0]
.split(':')[1]
.split(';')[0];
// write the bytes of the string to a typed array
let ia = new Uint8Array(byteString.length);
for (let i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
let blobImg = new Blob([ia], { type: mimeString });
console.log(blobImg);
this.blobImage = blobImg;
}
With this code, I am able to get image data but how to convert in a blob,
please help...
Hello #sergey-rudenko here my output
getPicture output:
imageDataURI: content://com.android.providers.media.documents/document/image%3A78702
this.file.resolveLocalFilesystemUrl output:
entry:
FileEntry {isFile: true, isDirectory: false, name: "image:78702", fullPath: "/com.android.providers.media.documents/document/image:78702", filesystem: FileSystem, …}
filesystem: FileSystem {name: "content", root: DirectoryEntry}
fullPath: "/com.android.providers.media.documents/document/image:78702"
isDirectory: false
isFile: true
name: "image:78702"
nativeURL: "content://com.android.providers.media.documents/document/image%3A78702"
__proto__: Entry
entry.file output:
file:
File {name: "content", localURL: "cdvfile://localhost/content/com.android.providers.media.documents/document/image%3A78702", type: "image/jpeg", lastModified: 1588099237000, lastModifiedDate: 1588099237000, …}
end: 79807
lastModified: 1588099237000
lastModifiedDate: 1588099237000
localURL: "cdvfile://localhost/content/com.android.providers.media.documents/document/image%3A78702"
name: "content"
size: 79807
start: 0
type: "image/jpeg"
__proto__: Object
const blob output:
Blob {size: 79807, type: "image/jpeg"}
size: 79807
type: "image/jpeg"
__proto__: Blob
formData output:
FormData {}
__proto__: FormData
append: ƒ append()
arguments: (...)
caller: (...)
length: 2
name: "append"
__proto__: ƒ ()
[[Scopes]]: Scopes[0]
delete: ƒ delete()
entries: ƒ entries()
forEach: ƒ forEach()
get: ƒ ()
getAll: ƒ getAll()
has: ƒ has()
keys: ƒ keys()
set: ƒ ()
values: ƒ values()
constructor: ƒ FormData()
Symbol(Symbol.iterator): ƒ entries()
Symbol(Symbol.toStringTag): "FormData"
__proto__: Object
In order to obtain the blob you need a few things:
First, make sure that the options of Camera plugin are set to return FILE_URI (URL to the binary file of the image):
options: CameraOptions = {
quality: 100,
destinationType: this.camera.DestinationType.FILE_URI, // set to FILE_URI
encodingType: this.camera.EncodingType.JPEG,
mediaType: this.camera.MediaType.PICTURE
};
Second, since FILE_URI is just a link and not actual file, you need a way to obtain it. You can do that using File plugin:
// Import it:
import {File, FileEntry} from '#ionic-native/file/ngx';
// Then use it in the method that Camera plugin has for taking pictures:
getPicture() {
this.camera.getPicture(this.options).then((imageDataURI) => {
this.file.resolveLocalFilesystemUrl(imageDataURI).then((entry: FileEntry) =>
{
entry.file(file => {
console.log(file);
this.readFile(file);
});
});
}, (err) => {
// Handle error
});
};
Lastly to send it to your server, you need to read the file:
read(file) {
const reader = new FileReader();
reader.onload = () => {
const blob = new Blob([reader.result], {
type: file.type
});
const formData = new FormData();
formData.append('name', 'MyImageBlob');
formData.append('file', blob, file.name);
this.service.upload(formData).subscribe(response => {
console.log(response);
});
};
reader.readAsArrayBuffer(file);
};
Let me know if you can take it from here.
Related
I have method that renders EJS templates and pass in the i18next.t function for the EJS template to do translations by setting the i18next t function as an attribute on the data object:
const data = {
email: user.email,
id: user.id,
t: i18nT
};
The data object is passed into ejs.renderFile(). The only way I can get the translation in the EJS template to work is when I set the i18nT variable to the t function from the i18next.init() functions call back. Otherwise it comes out blank. I see from the console output that the t function of the i18next instance, i18nInstance, is different to the t function set by the callback when initializing i18next.
function t() {
var _this$translator;
return this.translator && (_this$translator =
this.translator).translate.apply(_this$translator, arguments);
}
versus:
function () {
return _this4.t.apply(_this4, arguments);
}
Why is the t function of the i18nInstance object obtained from calling i18next.createInstance() different than the one from the callback? The one from the instance object doesn not work in the EJS template render.
The full code sample:
let i18nInstance: i18n;
let i18nT;
const i18nextInitOptions = {
backend: {
loadPath: path.join(__dirname, '/locales/{{lng}}/{{ns}}.json'),
addPath: path.join(__dirname, '/locales/{{lng}}/{{ns}}.missing.json')
},
debug: true,
fallbackLng: 'da',
preload: ['da', 'en', 'nl'],
returnEmptyString: false,
returnNull: false,
saveMissing: true
};
i18nInstance = await i18next
.createInstance();
await i18nInstance
.use(i18nextBackend)
.init(i18nextInitOptions, async function (error, t) {
if (error) {
console.log(error)
}
i18nT = t;
});
console.log("i18nT: " + i18nT)
/*
The console.log outputs below show that i18nT when set from the callback is different to the
i18nInstance.t.
i18nT: function () {
return _this4.t.apply(_this4, arguments);
}
*/
console.log("i18nInstance.t: " + i18nInstance.t)
/*
console output:
i18nInstance.t: function t() {
var _this$translator;
return this.translator && (_this$translator =
this.translator).translate.apply(_this$translator, arguments);
}
*/
const data1 = {
email: user.email,
id: user.id,
t: i18nT
};
// Calling htmlFromTemplate with data1 with t = i18nT the translation in the EJS template works.
html = await this.htmlFromTemplate('ejsTemplateName.ejs', data1);
const data2 = {
email: user.email,
id: user.id,
t: i18nextInstance.t
};
// Calling htmlFromTemplate with data2 with t = i18nextInstance.t the translation in the EJS is empty.
html = await this.htmlFromTemplate('ejsTemplateName.ejs', data2);
private htmlFromTemplate(templateName: string, data: Object): Promise<String> {
if (!templateName) return;
const htmlPath = path.join(__dirname, '../assets/mail-templates/' + templateName);
return new Promise((resolve, reject) => {
ejs.renderFile(htmlPath, data,(renderErr, str) => {
if (renderErr) {
appLogger.error('MAIL_RENDER: ' + renderErr, { templateName, data });
reject(renderErr);
} else resolve(str);
});
});
}
As soon as you pass the t function like this:
const data2 = {
email: user.email,
id: user.id,
t: i18nextInstance.t
};
the t function is not bound to its original "this" anymore...
pass it this way:
const data2 = {
email: user.email,
id: user.id,
t: i18nextInstance.t.bind(i18nextInstance)
};
more information here: https://github.com/i18next/i18next/issues/1528#issuecomment-748263313
I am having a problem taking a picture and uploading it to an S3 bucket when using FILE_URI for the camera.DestinationType. When using this same process with the DATA_URL DestinationType it works fine.
When using FILE_URI the file that gets uploaded to the S3 bucket says it's corrupt. I did notice the file size is much smaller (~100B) than an actual image.
Here are the versions I am using:
Ionic Framework 3.9.2 and cordova-plugin-camera 4.0.2
Here is the code I'm using:
const options: CameraOptions = {
quality: 100,
correctOrientation: true,
destinationType: this.camera.DestinationType.FILE_URI,
encodingType: this.camera.EncodingType.JPEG,
mediaType: this.camera.MediaType.PICTURE,
sourceType: this.camera.PictureSourceType.CAMERA,
}
this.camera.getPicture(options).then((imageData) => {
console.log(imageData);
let base64data = 'data:image/jpeg;base64,' + imageData;
this.bigImg = base64data;
// imageData is either a base64 encoded string or a file URI
// If it's base64:
this.selectedPhoto = this.dataURItoBlob(this.bigImg);
}, (err) => {
// Handle error
console.log("Get Image Error: " + err);
});
this.sub = AWS.config.credentials.identityId;
let uploadMessage = "Uploading Image...";
let photoName = "testPic";
this.upload(this.selectedPhoto, uploadMessage, photoName)
.then(data => {
// Change active page to list
this.navCtrl.setRoot(TabsPage).then(() => {
});
});
dataURItoBlob(dataURI) {
// code adapted from: http://stackoverflow.com/questions/33486352/cant-upload-image-to-aws-s3-from-ionic-camera
let binary = atob(dataURI.split(',')[1]);
let array = [];
for (let i = 0; i < binary.length; i++) {
array.push(binary.charCodeAt(i));
}
return new Blob([new Uint8Array(array)], {type: 'image/jpeg'});
};
upload(selectedPhoto, uploadMessage, photoName) {
return new Promise((resolve, reject) => {
let loading = this.loadingCtrl.create({
content: uploadMessage
});
loading.present();
if (selectedPhoto) {
this.s3.upload({
'Key': 'protected/' + this.sub + '/' + photoName,
'Body': selectedPhoto,
'ContentType': 'image/jpeg'
}).promise().then((data) => {
this.data2 = data;
console.log('upload complete:', JSON.stringify(data));
loading.dismiss();
resolve(data);
}, err => {
console.log('upload failed....', JSON.stringify(err));
loading.dismiss();
reject(err);
});
} else {
loading.dismiss();
reject("upload failed");
}
});
I have this working fine with get.JSON but when I try and use the fetch API instead, it gives me the error "Required parameter: part".
export const fetchYoutube = () => {
return dispatch => {
fetchAsync()
.then(data => console.log(data))
.catch(reason => console.log(reason.message))
dispatch({
type: INCREMENT
})
}
}
async function fetchAsync () {
var query = {
part: 'snippet',
key: 'AIzaSyA3IHL73MF00WFjgxdwzg57nI1CwW4dybQ',
maxResults: 6,
type: 'video',
q: 'music'
}
let response = await fetch('https://www.googleapis.com/youtube/v3/search', {
data : query,
method: 'GET'
});
let data = await response.json();
return data;
}
How do I pass the query object using the fetch API?
Try attaching the query as params:
replace:
let response = await fetch('https://www.googleapis.com/youtube/v3/search', {
data : query,
method: 'GET'
});
with:
var url = new URL("https://www.googleapis.com/youtube/v3/search"),
query = {
part: 'snippet',
key: '#####################################',
maxResults: 6,
type: 'video',
q: 'music'
}
Object.keys(query).forEach(key => url.searchParams.append(key, query[key]))
let response = await fetch(url)
Setting query string using Fetch GET request
I'm using ionic2: I want to upload an image from the gallery, crop it and send it to a server.
uploadImage(): Promise<any> {
var status = 'upload';
return new Promise(resolve =>
{
const options: CameraOptions = {
quality: 100,
sourceType: 2,
destinationType: this.camera.DestinationType.DATA_URL,
mediaType: this.camera.MediaType.PICTURE,
allowEdit: true
}
this.camera.getPicture(options).then((imageData) => {
// imageData is either a base64 encoded string or a file URI
// If it's base64:
this.base64Image = "data:image/jpeg;base64",imageData;
console.log("imaaage ",this.base64Image);
resolve(this.base64Image);
}, (err) => {
console.log("error")
});
});
}
the problem is that: I want destinationType to be FILE_URL to send it, at the same time I want it to be DATA_URL to display it to the user.
what should I do to solve this problem?
hello can any one guide me in my ajax request its always show me only eight record .
$(this).typeahead({
source: function (query, process) {
jQuery.ajax({
url: url + "/ajax/productdetail",
type: 'GET',
limit: 10,
data: {
cat: $type,
name: query,
form: $form,
setupid: $setupid
},
dataType: 'json',
success: function (response) {
objects = [];
map = {};
$.each(response, function (i, object) {
//debugger;
map[object.name] = object;
objects.push(object.name);
});
process(objects);
}
});
}
});
Just add an option "items" while instantiating the typeahead method. Hope the below sample will help you to understand.
$('input#auto-complete-field').typeahead({
minLength : 0,
items: 9999,
source: function (query, process) {
objects = [];
map = {};
$.ajax({
.......
......
});
}
updater: function(item) {
.............
.............
}
});