Google Document Viewer shows: the server cannot process the request because it is malformed - google-chrome

I try to preview the documents on my site using Google viewer. Document url I get from blob, but when I click to show docs I had an error.
In console I see this link: blob:http://localhost:8080/5372d78d-a9c6-4c50-b23b-249cc643bdd2
const url = window.URL.createObjectURL(
new Blob([response.data], { type: response.data.type })
);
const link = document.createElement("iframe");
console.log(url);
link.src = `https://docs.google.com/viewer?url=${url}&embedded=true`;
link.style.width = "100%";
link.style.height = "500px";
document.getElementById(fileId).appendChild(link);
},```
```async showDoc(file) {
this.fileId = file.Document.Id;
this.fileName = file.Document.Name;
try {
let response = await axios.get(url, {
responseType: "blob",
params: {
fileId: this.fileId,
},
});
this.forceFileShow(response, this.fileId);
console.log("удача", response);
} catch (err) {
console.log("неудача", err.response);
}
}
},
And here html:
<div class="card-icon" #click="showDoc(file)"
:data-target="`#showDoc${file.Document.Id}`"
data-toggle="modal">```
[1]: https://i.stack.imgur.com/tZlkm.png

Related

Google drive picker API "this.qi is not a function"

I am trying to load the google drive picker API in my project.
This source code is taken from Google Picker Code Sample
This is my source code.
gapiLoaded() {
window['gapi'].load('client:picker', this.intializePicker);
}
async intializePicker() {
await window['gapi'].client.load('https://www.googleapis.com/discovery/v1/apis/drive/v3/rest');
}
gisLoaded() {
this.tokenClient = window['google'].accounts.oauth2.initTokenClient({
client_id: MY_Client_Id,
scope: 'https://www.googleapis.com/auth/drive.readonly',
callback: '', // defined later
});
this.gisInited = true;
}
handleAuthClick() {
this.tokenClient.callback = async (response) => {
if (response.error !== undefined) {
throw (response);
}
this.accessToken = response.access_token;
this.createPicker();
};
if (this.accessToken === null) {
this.tokenClient.requestAccessToken({prompt: 'consent'});
} else {
this.tokenClient.requestAccessToken({prompt: ''});
}
}
createPicker() {
var view = window['google'].picker.View(window['google'].picker.ViewId.DOCS);
var picker = window['google'].picker.PickerBuilder()
.enableFeature(window['google'].picker.Feature.NAV_HIDDEN)
.enableFeature(window['google'].picker.Feature.MULTISELECT_ENABLED)
.setDeveloperKey('MY_APP_KEY')
.setAppId('MY_PROJECT_ID')
.setOAuthToken(this.accessToken)
.addView(view)
.addView( window['google'].picker.DocsUploadView())
.setCallback(this.pickerCallback)
.build();
picker.setVisible(true);
}
async pickerCallback(data) {
if (data.action === window['google'].picker.Action.PICKED) {
let text = `Picker response: \n${JSON.stringify(data, null, 2)}\n`;
const document = data[window['google'].picker.Response.DOCUMENTS][0];
const fileId = document[window['google'].picker.Document.ID];
console.log(fileId);
const res = await window['gapi'].client.drive.files.get({
'fileId': fileId,
'fields': '*',
});
text += `Drive API response for first document: \n${JSON.stringify(res.result, null, 2)}\n`;
console.log(text)
}
}
When I run this code, I am getting this error "this.Qi is not a function". The error arise at Picker builder function. How to resolve this?

Html to Pdf Format Angular

Hello i want to convert from html to pdf format and send it as a file to my backend, so i can save it in my server, i tried using jspdf but its not working
SendMail() {
var doc = new jspdf();
doc.fromHTML('<h1>Hello World!</h1>', 20, 20);
var blob = new Blob([doc.output("blob")], { type: "application/pdf" });
let lruta = 'report/' + 'test';
this.uploaderService.uploadfile(blob, lruta).subscribe(
response => {
this.fetcher = response;
this.blockUI.stop();
}, error => {
this.blockUI.stop();
}
);
}
This is my service UploadFile
uploadfile(cabecera, ruta) {
const formData = new FormData();
formData.append('file', cabecera[0]);
formData.append('ruta', ruta);
return this._http.post(this.apiUrl + this.serviceUrl + 'gestion/uploadrevision', formData);
}
When i replace blob with this.file in my this.uploaderService.uploadfile
it works, but i dont want to download and upload my file
file: any;
onFileChange(event) {
this.file = event.target.files;
}

Ionic 4 : Recording Audio and Send to Server (File has been corrupted)

I would like to record the audio file in mobile application(iOS & Android) and tranfer to server as a formData in ionic 4. I have used the "cordova-plugin-media" to capture the audio using below logics
if (this.platform.is('ios')) {
this.filePaths = this.file.documentsDirectory;
this.fileExtension = '.m4a';
} else if (this.platform.is('android')) {
this.filePaths = this.file.externalDataDirectory;
this.fileExtension = '.3gp';
}
this.fileName = 'recording'+new Date().getHours()+new Date().getMinutes()+new Date().getSeconds()+this.fileExtension;
if(this.filePaths) {
this.file.createFile(this.filePaths,this.fileName,true).then((entry:FileEntry)=> {
this.audio = this.media.create(entry.toInternalURL());
this.audio.startRecord();
});
}
Even I have tried to create the media directly without "File Creation"
I can record and play the audio, but If I am trying to send this file
to server using below logics It won't send properly(corrupted data)
and also web application unable to play .m4a extensions
.
Please correct me If I am doing anything wrong in my code
Upload logic:
let formData:FormData = new FormData();
formData.append('recordID' , feedbackID);
that.file.readAsDataURL(filePath,file.name).then((data)=>{
const audioBlob = new Blob([data], { type: file.type });
formData.append('files', audioBlob, file.name);
that.uploadFormData(formData,feedbackID); //POST Logics -
})
;
I have used the soultion as suggested by Ankush and it works fine.
Used readAsArrayBuffer instead of readAsDataURL.
The .m4a format has supported both ios and android. Also I can
download the the same file from web application.
I am using below code to upload the image to the server. I assume that only a few modifications will be required in this code to transfer media instead of the image file.
private uploadPicture(imagePath: string, apiUrl: string): Observable<ApiResponse<ImageUploadResponseModel>> {
return this.convertFileFromFilePathToBlob(imagePath).pipe(
switchMap(item => this.convertBlobToFormData(item)),
switchMap(formData => this.postImageToServer(formData, apiUrl))
);
}
Rest functions used in above code:
private postImageToServer(formData: FormData, apiUrl: string): Observable<ApiResponse<ImageUploadResponseModel>> {
const requestHeaders = new HttpHeaders({ enctype: 'multipart/form-data' });
return this.http.post<ApiResponse<ImageUploadResponseModel>>(apiUrl, formData, { headers: requestHeaders });
}
private convertBlobToFormData(blob: Blob): Observable<FormData> {
return new Observable<FormData>(subscriber => {
// A Blob() is almost a File() - it's just missing the two properties below which we will add
// tslint:disable-next-line: no-string-literal
blob['lastModifiedDate'] = new Date();
// tslint:disable-next-line: no-string-literal
blob['name'] = 'sample.jpeg';
const formData = new FormData();
formData.append('file', blob as Blob, 'sample.jpeg');
subscriber.next(formData);
subscriber.complete();
});
}
private convertFileFromFilePathToBlob(imagePath: string): Observable<Blob> {
return new Observable<Blob>(subscriber => {
const directoryPath = imagePath.substr(0, imagePath.lastIndexOf('/'));
let fileName = imagePath.split('/').pop();
fileName = fileName.split('?')[0];
this.file.readAsArrayBuffer(directoryPath, fileName).then(fileEntry => {
const imgBlob: any = new Blob([fileEntry], { type: 'image/jpeg' });
imgBlob.name = 'sample.jpeg';
subscriber.next(imgBlob);
subscriber.complete();
}, () => {
subscriber.error('Some error occured while reading image from the filepath.');
});
});
}

WebRTC video chat for Firefox-to-Chrome and Chrome-to-Firefox not working

I'm trying to implement a very simple video chat based on the WebRTC API.
Unfortunately my Code is just working from Chrome-to-Chrome and from Firefox-to-Firefox so far.
If I try it from Chrome-to-Firefox or from Firefox-to-Chrome I get the following error output:
Failed to set local offer sdp: Session error code: ERROR_CONTENT. Session error description: Failed to set local video description recv parameters..(anonymous function) # helloWebRtc.js:126***
Did I possibly missed something or do I need some flags in the Chrome or Firefox browser?
Do you have any idea? I would be grateful for any help I can get to solve this issue.
Thank you all in advance!
My helloWebRtc.js looks like this:
var localVideo = document.querySelector("#localVideo");
var remoteVideo = document.querySelector("#remoteVideo");
var SIGNAL_ROOM = "signal_room";
var CHAT_ROOM = "chat_room";
var serverConfig = {
"iceServers": [
{
"urls": "stun:stun.l.google.com:19302"
}
]
};
var optionalConfig = {
optional: [
{
RtpDataChannels: true
},
{
DtlsSrtpKeyAgreement: true
}
]
};
var rtcPeerConn,
localStream;
io = io.connect();
io.emit("ready", {"chat_room": CHAT_ROOM, "signal_room": SIGNAL_ROOM});
io.emit("signal", {
"room": SIGNAL_ROOM,
"type": "user_here",
"message": "new user joined the room"
});
io.on("rtcSignaling", function(data) {
if(!rtcPeerConn) {
startSignaling();
}
if(data.type !== "user_here" && data.message) {
var message = JSON.parse(data.message);
if(message.description) {
var remoteDesc = new RTCSessionDescription(message.description);
rtcPeerConn.setRemoteDescription(remoteDesc, function() {
// if we receive an offer we need to answer
if(rtcPeerConn.remoteDescription.type === "offer") {
rtcPeerConn.createAnswer(sendLocalDescription, function(error) {
console.error("error on creating answer", error);
});
}
}, function(error) {
console.error("error on set remote description", error);
});
} else if(message.candidate) {
var iceCandidate = new RTCIceCandidate(message.candidate);
rtcPeerConn.addIceCandidate(iceCandidate);
}
}
});
function startSignaling() {
rtcPeerConn = new RTCPeerConnection(serverConfig, optionalConfig);
//send any ice candidate to the other peer
rtcPeerConn.onicecandidate = function(event) {
if(event.candidate) {
io.emit("signal", {
"room": SIGNAL_ROOM,
"type": "candidate",
"message": JSON.stringify({
"candidate": event.candidate
})
});
}
};
rtcPeerConn.onnegotiationneeded = function() {
rtcPeerConn.createOffer(sendLocalDescription, function(error) {
console.error("error on creating offer", error);
});
};
// add the other peer's stream
rtcPeerConn.onaddstream = function(event) {
console.info("on add stream called");
remoteVideo.srcObject = event.stream;
};
// add local stream
navigator.mediaDevices.getUserMedia({
audio: true,
video: true
})
.then(function(stream) {
localVideo.srcObject = stream;
localStream = stream;
rtcPeerConn.addStream(localStream);
})
.catch(function(e) {
alert('getUserMedia() error: ' + e.name);
});
}
function sendLocalDescription(description) {
rtcPeerConn.setLocalDescription(
description,
function() {
io.emit("signal", {
"room": SIGNAL_ROOM,
"type": "description",
"message": JSON.stringify({
"description": rtcPeerConn.localDescription
})
});
},
function(error) {
console.error("error to set local desc", error);
}
);
}
My NodeJS server (using express.io) looks like the following:
var express = require('express.io');
var app = express();
var PORT = 8686;
app.http().io();
console.log('server started # localhost:8686');
// declaring folders to access i.e.g html files
app.use(express.static(__dirname + '/views'));
app.use('/scripts', express.static(__dirname + '/scripts'));
// root url i.e. "localhost:8686/"
app.get('/', function(req, res) {
res.sendFile('index.html');
});
/**
* Socket.IO Routes for signaling pruposes
*/
app.io.route('ready', function(req) {
req.io.join(req.data.chat_room);
req.io.join(req.data.signal_room);
app.io.room(req.data.chat_room).broadcast('announce', {
message: 'New client in the ' + req.data.chat_room + ' room.'
});
});
app.io.route('send', function(req) {
app.io.room(req.data.room).broadcast('message', {
message: req.data.message,
author: req.data.author
});
});
app.io.route('signal', function(req) {
// Note: req means just broadcasting without letting the sender also receive their own message
if(req.data.type === "description" || req.data.type === "candidate")
req.io.room(req.data.room).broadcast('rtcSignaling', {
type: req.data.type,
message: req.data.message
});
else
req.io.room(req.data.room).broadcast('rtcSignaling', {
type: req.data.type
});
});
app.listen(PORT);
You can compare the offer SDP generated by the chrome and firefox, there might be some difference which is not interoperable to other.
Edit to the old answer below: there are several bugs in interoperability between Chrome and Firefox. Someone from the webrtc team gave me the suggestion to keep the offerer to the same party. So if A creates an offer when setting up a stream to B, then B asks A to create a new offer, instead of creating one self, when setting up a stream to A.
See also here:
https://bugs.chromium.org/p/webrtc/issues/detail?id=5499#c15
I did note that if Firefox initiates a session, Chrome will kick the stream coming from Firefox out of the video element but you can create a new object URL on the stream and set it as the source.
Hope that helps.
Old message:
I am experiencing the same thing, so if you have an answer, I'm curious.
I do believe that there is a mismatch (bug) between FireFox and Chrome in setting up DTLS roles, see also:
https://bugs.chromium.org/p/webrtc/issues/detail?id=2782#c26
just check if you are setting DtlsSrtpKeyAgreement parameter to true while you create the peerconnection.
pc = new RTCPeerConnection(pc_config,{optional: [{RtpDataChannels: true},{
DtlsSrtpKeyAgreement: true}]});

How to import json file into indexeddb?

I am doing an app that store some data in the IndexedDB, but I want to load first some data that is in my json file.
Here is my json file:
{
"ciudades":[
{
"ciudad":"Asuncion",
"latitud":-25.2985296,
"longitud":-57.6710677
},
{
"ciudad":"Caaguazu",
"latitud":-25.465034,
"longitud":-56.0183859
},
{
"ciudad":"Ciudad del Este",
"latitud":-25.4933441,
"longitud":-54.6710438
},
{
"ciudad":"San Pedro",
"latitud":-24.1586759,
"longitud":-56.636503
},
{
"ciudad":"Pedro Juan Caballero",
"latitud":-22.5450875,
"longitud":-55.7618963
}
]
}
you follow step
step 1 read mozilla site
step 2 create indexedDB
var ciudades = [
{
"ciudad":"Asuncion",
"latitud":-25.2985296,
"longitud":-57.6710677
},
{
"ciudad":"Caaguazu",
"latitud":-25.465034,
"longitud":-56.0183859
},
{
"ciudad":"Ciudad del Este",
"latitud":-25.4933441,
"longitud":-54.6710438
},
{
"ciudad":"San Pedro",
"latitud":-24.1586759,
"longitud":-56.636503
},
{
"ciudad":"Pedro Juan Caballero",
"latitud":-22.5450875,
"longitud":-55.7618963
}
];
var IDBSetting = {
name: "indexedDBName",
version: 1,
tables: [{
tableName: "ciudades",
keyPath: "seq",
autoIncrement: true,
index: ["ciudad", "latitud", "longitud],
unique: [false, false, false]
}]
};
! function() {
console.log("indexeDB init");
var req = indexedDB.open(IDBSetting.name, IDBSetting.version);
req.onsuccess = function(event) {
console.log("indexedDB open success");
};
req.onerror = function(event) {
console.log("indexed DB open fail");
};
//callback run init or versionUp
req.onupgradeneeded = function(event) {
console.log("init onupgradeneeded indexedDB ");
var db = event.target.result;
for (var i in IDBSetting.tables) {
var OS = db.createObjectStore(IDBSetting.tables[i].tableName, {
keyPath: IDBSetting.tables[i].keyPath,
autoIncrement: IDBSetting.tables[i].autoIncrement
});
for (var j in IDBSetting.tables[i].index) {
OS.createIndex(IDBSetting.tables[i].index[j], IDBSetting.tables[i].index[j], {
unique: IDBSetting.tables[i].unique[j]
});
}
}
}
}();
step 3 addData
var IDBFuncSet = {
//write
addData: function(table, data) {
var req = indexedDB.open(IDBSetting.name, IDBSetting.version);
req.onsuccess = function(event) {
try {
console.log("addData indexedDB open success");
var db = req.result;
var transaction = db.transaction([table], "readwrite");
var objectStore = transaction.objectStore(table);
var objectStoreRequest = objectStore.add(data);
} catch (e) {
console.log("addDataFunction table or data null error");
console.log(e);
}
objectStoreRequest.onsuccess = function(event) {
//console.log("Call data Insert success");
}
objectStoreRequest.onerror = function(event) {
console.log("addData error");
}
};
req.onerror = function(event) {
console.log("addData indexed DB open fail");
};
}
}
for(var i in ciudades){
IDBFuncSet.addData("ciudades",ciudades[i]);
}
step 4 getData
IDBFuncSet.getAllData = function(arr, table) {
try {
var req = indexedDB.open(IDBSetting.name, IDBSetting.version);
req.onsuccess = function(event) {
var db = req.result;
var transaction = db.transaction([table], "readonly");
var objectStore = transaction.objectStore(table);
var objectStoreRequest = objectStore.openCursor();
objectStoreRequest.onsuccess = function(event) {
var cursor = event.target.result;
if (cursor) {
arr.push(cursor.value);
cursor.continue();
} else {
}
}
};
req.onerror = function(event) {
console.log("getAllData indexed DB open fail");
};
} catch (e) {
console.log(e);
}
}
var ciudadesArr = [];
IDBFuncSet.getAllData(ciudadesArr, "ciudades");
console.log(ciudadesArr);
I hope this helps
Here's how I've done mine, thanks to the android-indexeddb package.
angular.module('yourApp', ['indexedDB'])
.config(function($indexedDBProvider) {
$indexedDBProvider
.connection('dbName')
.upgradeDatabase(1, function(event, db, tx) {
var objStore = db.createObjectStore('storeOne', { keyPath: 'stop_id' });
objStore.createIndex('store_id', 'store_id', { unique: false });
})
// the next upgradeDatabase() function is necessary if you
// wish to create another datastore
.upgradeDatabase(2, function(event, db, tx) {
var secondObjectStore = db.createObjectStore('storeTwo', { keyPath: 'my_id' });
secondObjectStore.createIndex('another_id', 'another_id', { unique: false });
});
})
Then in my controller:
angular.module('yourApp')
.controller('homeCtrl', ['$scope', '$http', '$indexedDB', function($scope, $http, $indexedDB) {
$scope.objects = [];
var loadJSON = function(file_name) { ... //load the json file in here}
$indexedDB.openStore('storeOne', function(store) {
var loaded = loadJSON('file_name.json');
store.upsert(loaded).then(function(e) {
console.log('added successfully');
});
});
$indexedDB.openStore('times', function(store) {
var loaded = loadJSON('file_name.json');
store.upsert(loaded).then(function(e) {
console.log('added successfully');
});
});
}]);
Check out the project page to learn more of the tricks up this package's sleeves.
Although this angular-indexeddb page supports queries, for advanced queries like joins, you might wanna consider ydn-db
Getting some pretty nice workflow with both packages.
For the loadJSON() function, it could be something like this:
var loadJSON = function(file_name) {
var data;
$.ajax({
url: '../data/' + file_name,
dataType: 'json',
async: false,
success: function(res_data) {
data = res_data;
console.log('Loaded ' + file_name + ' nicely');
},
error: function(err) {
console.log('error happened');
}
});
return data;
}
There is File API, but that doesn't seem to be a solid standard yet.
What I do at the moment, is have the user open the file, copy it's contents to Clipboard, and paste it into a TextArea element on my web page.
In JavaScript I add a listener to the TextArea's change event and parse the text content into JSON, which is then written to indexedDB.