Is it possible to use POST to set the results of a SurveyJS survey?
I can use GET to get the survey results, but I am struggling with setting.
Here is the code I use to GET the results:
urlToSurvey = "https://dxsurvey.com/api/MySurveys/getSurveyResults/surveyID?accessKey=myKey";
$.get(urlToSurvey, function(res) {
console.log(res);
});
I want to use SurveyJS to store students' progress in an open-source plugin (Adapt Learning), so I want to directly post the progress data to SurveyJS as I cannot run a stand-alone html in the plugin.
Any help is appreciated. Thanks!
You can check this file - https://github.com/surveyjs/surveyjs/blob/master/src/dxSurveyService.ts
Here is the code responsible for sending the result:
public sendResult(
postId: string,
result: JSON,
onSendResult: (success: boolean, response: any) => void,
clientId: string = null,
isPartialCompleted: boolean = false
) {
var xhr = new XMLHttpRequest();
xhr.open("POST", dxSurveyService.serviceUrl + "/post/");
xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8");
var data = { postId: postId, surveyResult: JSON.stringify(result) };
if (clientId) data["clientId"] = clientId;
if (isPartialCompleted) data["isPartialCompleted"] = true;
var dataStringify: string = JSON.stringify(data);
var self = this;
xhr.onload = xhr.onerror = function() {
if (!onSendResult) return;
onSendResult(xhr.status == 200, xhr.response);
};
xhr.send(dataStringify);
}
The required params are the postId and result json. You can get your postId from the MySurveys page of the service (https://surveyjs.io/Service/MySurveys/ note that MySurveys page requires authorization).
This is a TypeScript code, but I'm sure it can easily be converted to the JS.
Related
I'm tyring to upload a static json file into an indexedDB ONLY when an upgrade is needed (i.e. onupgradeneeded). I've search for answers to this repeatedly but have yet to see code examples of how to approach this.
My current code below gets the json file every time the page opens, which is of course inefficient since I only need to get the json file if the indexedDB has not yet been created or needs upgraded.
I tried putting the xhr.onload section into the end of the .onupgradeneeded function, but as many have noted, the .onsuccess gets called before the xhr.onload has completed.
var jsonUrl = '/path/to/hcLookup.json');
var req, db, hcObjectStore, objectStore, data, dataArr, trans, addreq, key;
var xhr = new XMLHttpRequest();
xhr.open("GET", jsonUrl, true);
xhr.type='json';
xhr.send();
xhr.onload = function(msg) {
data = msg.target.response;
req = window.indexedDB.open("hcLookup", 1);
req.onerror=function(event){console.log("onerror: " + event.target.errorCode)};
req.onsuccess = function(event){
console.log("ready.");
};
req.onupgradeneeded = function(event){
db = event.target.result;
objectStore = db.createObjectStore("hcLookup", {autoIncrement: true});
objectStore.createIndex("S", "S", {unique: false});
// make sure the objectStore creation is finished before adding data into it
objectStore.transaction.oncomplete = function (event) {
// Store values in the newly created objectStore.
trans = db.transaction(["hcLookup"], "readwrite");
hcObjectStore = trans.objectStore("hcLookup");
// Do something when all the data is added to the database.
trans.oncomplete = function (event) {
console.log("upgrading done!");
};
trans.onerror = function (event) {
console.log("bulk add onerror: " + event.target.errorCode)
};
//convert JSON to an strArray in order to add the dataArr into to the objectStore
dataArr = JSON.parse(data);
for (var i in dataArr) {
addreq = hcObjectStore.add(dataArr[i]);
}
};
};
};
I was following the below links for displaying pdf page in new tab in my angular 5 application. But unable to achieve the result.
I am consuming the bytes array from spring controller api.
PDF Blob is not showing content, Angular 2
PDF Blob - Pop up window not showing content
Angular2 Displaying PDF
I tried the below options but none of them is working.
Trial 1
Consumed the response as json
component.ts
clickEvent(){
this.service.getPDF().subscribe((response)=>{
let file = new Blob([response.byteString], { type: 'application/pdf' });
var fileURL = URL.createObjectURL(file);
window.open(fileURL);
})
}
service.ts
getPDF(){
const url = `${this.serviceUrl}/pdf`;
const httpOptions = {
headers: new HttpHeaders(
{
'Accept': 'application/json',
'responseType':'blob'
}
)
};
return this.http.get<any>(url, httpOptions);
}
Trial 2
Consumed the response as json
component.ts
clickEvent(){
this.service.getPDF().subscribe((response)=>{
let file = new Blob([response.byteArray], { type: 'application/pdf' });
var fileURL = URL.createObjectURL(file);
window.open(fileURL);
})
}
service.ts
getPDF(){
const url = `${this.serviceUrl}/pdf`;
const httpOptions = {
headers: new HttpHeaders(
{
'Accept': 'application/json',
'responseType':'arraybuffer'
}
)
};
return this.http.get<any>(url, httpOptions);
}
Trial 3
Consumed the response as bytes
component.ts
clickEvent(){
this.service.getPDF().subscribe((response)=>{
let file = new Blob([response], { type: 'application/pdf' });
var fileURL = URL.createObjectURL(file);
window.open(fileURL);
})
}
service.ts
getPDF(){
const url = `${this.serviceUrl}/pdf`;
const httpOptions = {
headers: new HttpHeaders(
{
'responseType':'blob' //both combination
//'responseType' : 'arraybuffer'
}
)
};
return this.http.get<any>(url, httpOptions);
}
By all the combination I am only getting two results.
Empty pdf document or Failed to load PDF document.
For understanding posting java spring controller code.
controller.java
#GetMapping(value = "/pdf")
public ResTest generatePDF(HttpServletResponse response) throws IOException {
ResTest test = new ResTest();
ByteArrayOutputStream baos = docTypeService.createPdf();
test.setByteArray(baos.toByteArray());
test.setByteString(new String(baos.toByteArray()));
return test;
}
At last, I was able to render pdf. There were two small mistakes from my side.
1 st Problem was, I gave 'responseType' inside HttpHeaders which was wrong.
It should be outside as below.
2 nd Problem was, even though if you mention as responseType : 'arraybuffer', it was unable to take it. For that you need to mention as responseType : 'arraybuffer' as 'json'.(Reference)
The corrected and working code below.
Trial 3
component.ts (nochanges)
clickEvent(){
this.service.getPDF().subscribe((response)=>{
let file = new Blob([response], { type: 'application/pdf' });
var fileURL = URL.createObjectURL(file);
window.open(fileURL);
})
service.ts
getPDF(){
const url = `${this.serviceUrl}/pdf`;
const httpOptions = {
'responseType' : 'arraybuffer' as 'json'
//'responseType' : 'blob' as 'json' //This also worked
};
return this.http.get<any>(url, httpOptions);
}
Referred from the below link
https://github.com/angular/angular/issues/18586
I had the same problem with angular and pdf display. I will describe my solution - use base64 encoded string. All modern browsers support base64.
Use import java.util.Base64 to decode your byte array
byte[] bytes = baos.toByteArray();
String string = Base64.getEncoder().encodeToString(bytes);
test.setByteString(string);
On the frontend side use standard mime type for pdf and indicate that you are using base64 data:application/pdf;base64,.
Ref. to mime types: https://en.wikipedia.org/wiki/Media_type
If you need to open document in a new window:
let newPdfWindow = window.open("","Print");
let content = encodeURIComponent(response.byteString);
let iframeStart = "<\iframe width='100%' height='100%' src='data:application/pdf;base64, ";
let iframeEnd = "'><\/iframe>";
newPdfWindow.document.write(iframeStart + content + iframeEnd);
If you need to open in a new tab, you may simply provide to your html href:
let pdfHref = this.sanitizer.bypassSecurityTrustUrl('data:application/octet-stream;base64,' + content);
bypassSecurityTrustUrl will sanitize your url. As I remember there was some problem with angular security, that prevented me from seeing the content.
PS. before checking how it works with angular I would like to recommend you to store the pdf file on a drive and try to open it. I mean, that you should be certainly sure that you file is valid and you may open it with simple reader.
Update. The simpliest solution is to use pdf.js library https://github.com/mozilla/pdf.js
Have you looked for an angular component to wrap pdf.js?
https://github.com/VadimDez/ng2-pdf-viewer
Sample usage:
<pdf-viewer [src]="pdfSrc"
[render-text]="true"
style="display: block;">
</pdf-viewer>
pdfSrc can be a url string or a UInt8Array
When you make AJAX call to get PDF/file stream
var req = this.getYourPDFRequest(fd);
this.postData(environment.previewPDFRFR, req).then(res => {
res.blob().then(blob => {
const fileURL = URL.createObjectURL(blob);
window.open(fileURL, '', 'height=650,width=840');
})
});
If ur byte array comes from a .net backend u have to return
return File(doc.BinaryData, "application/pdf"); // page visible in typescript
, and not this :
return Ok(doc.BinaryData); // page blank in typescript
I have a fairly simple controller that gets a simple json list of objects ...
function ProductGroupsCtrl($scope, $http, $routeParams, sharedService, popupService) {
$scope.list = null;
$scope.selectedItem = null;
$scope.selectedItemJsonString = '';
$scope.selectItem = function (item) {
$scope.selectedItem = item;
$scope.selectedItemJsonString = JSON.stringify(item);
//alert(JSON.stringify(item));
};
$scope.closePopup = function () {
$scope.selectedItem = null;
$scope.selectedItemJsonString = '';
};
// sharedService.prepForBroadcast($routeParams.anotherVar);
$http({
method: 'GET',
url: '/ProductGroup'
}).success(function (data) {
$scope.list = data;
}).
error(function (data) {
$scope.message = 'There was an error with the data request.';
});
}
I then try to mock the request in the test class:
var scope, ctrl, $httpBackend, sharedServiceMock = {}, popupServiceMock = {};
beforeEach(inject(function (_$httpBackend_, $rootScope, $controller) {
$httpBackend = _$httpBackend_;
$httsypBackend.expectGET('/ProductGroup').
respond([{
ProductGroupID: 5,
MenuTitle: "Promotional Products",
AlternativeText: "Coming soon - a collection of environmentally friendly Promotional Products",
OrdinalPosition: 5,
Active: false
}]);
scope = $rootScope.$new();
ctrl = $controller(ProductGroupsCtrl, {
$scope: scope,
$http: $httpBackend,
sharedService: sharedServiceMock,
popupService: popupServiceMock
});}));
However I receive an error in the testacular window object undefined. What have I done wrong here?
Found the answer. If I remove the error callback function from the $http.get method then it works, i.e. remove the following ...
error(function (data) {
$scope.message = 'There was an error with the data request.';
}
I have to say Angular sure is a steep learning curve for someone who is not a day to day JavaScript programmer (although I seem to be doing more and more). Thanks for the help anyway KatieK :-)
I have used Ti.Network.createHTTPClient in Titanium and see that the control goes neither inside onLoad nor onError. What could be the reason?
var loader = Titanium.Network.createHTTPClient();
loader.onload = function() {
alert("Hello");
}
loader.onError = function(e)
alert("Error: " + e.error);
}
Add these 2 lines to make it work! You did not send the request, nor did you send the URL
// add url in here
loader.open("GET",'[URL HERE]');
// Send the request.
loader.send();
var xhrSitelogin = Titanium.Network.createHTTPClient();
xhrSitelogin.open('POST', webservice_url);
xhrSitelogin.send({
method : "userlogin",
username : username,
password : password
});
xhrSitelogin.setTimeout(10000);
xhrSitelogin.onerror = function() {
showAlertBox('Service timed out. Please try again.');
//Hide Indicator
};
xhrSitelogin.onload = function() {
alert(this.responseText);
//RESPONSE RECEIVED
};
Vote Up or mark best if you consider it help full.
Hi dosth try with this am not sure it will work if it work i will be happy
var taskRequest = Titanium.Network.createHTTPClient();
var api_url = 'http://myawesomeapi.heroku.com/users/' +
Ti.App.Properties.getString("userID") + '/tasks';
taskRequest.onload = function() {
var tasks = [];
// code populating the tasks array
alert(tasks);
callback( tasks ); // invoke the callback
}
taskRequest.open('GET', api_url, false);
taskRequest.setRequestHeader('Content-Type', 'application/json');
taskRequest.send();
<....>
loader.open("POST/GET","URL");
loader.onload(response){
//get the response
console.log(this.responseText);
};
loader.send();
Use this pattern.
If you need to set any header then use loader.setRequestHeader("Content-Type", "application/json; charset=utf-8"); after the open()/before onload() and send()
I can't find anything in the docs on exactly how to do this.
http://nodejs.org/api.html#request-method-149
I need to make a Node js POST with authorization something similar to this in ruby:
url = URI.parse('http://www.example.com/todo.cgi')
req = Net::HTTP::Post.new(url.path)
req.basic_auth 'jack', 'pass'
I am trying to essentially do this:
var client = http.createClient(80, 'http://api.foo.com');
var rq = client.request('POST', '/path/',
{
'authorization' : [account, password]
'key': value,
etc....
}
Just encode the string account:password in base64 using a Buffer and set it has header with the key Authorization, prefixed with the word Basic.
Here's an example for us more ignorant (Improvements can be made!). Works for twitter's streaming API. Listen for response and then data, as per usual when making requests.
var hackClient = http.createClient(80, 'stream.twitter.com');
var request = hackClient.request("GET", '/1/statuses/filter.json?'+querystring.stringify(params),{
"Host":"stream.twitter.com",
"Authorization":"Basic " + new Buffer('user' + ":" + 'pass').toString('base64'),
"User-Agent": "Twitter-Node"
});
request.on('response', function(response) {
response.on('data', function(chunk) {
stream.receive(chunk); //example usage, no stream object in this example exists
});
response.on('error', function(error) {
stream.emit('error', error); //again, for example
});
response.on('end', function () {
stream.emit('end');
});
});
request.on('error', function(error) {
stream.emit('error', error);
});