When running my JavaScript, fires on button click on the form pictured left, I get several logs at points in my code. The JavaScript fires off an XHR request to an external API.
When I click into any of the links to my file from the console output I'm brought there. Before I would navigate to my JavaScript file, but can not seem to anymore.
JavaScript source code
function HandleSyncTask(commandProperties, primaryControl) {
console.log("HandleSyncTask running...");
openSyncTaskConfirmDialog(commandProperties, primaryControl);
}
function openSyncTaskConfirmDialog(commandProperties, primaryControl) {
console.log("Opening confirm dialog...");
var confirmStrings = {
cancelButtonLabel: "No",
confirmButtonLabel: "Yes",
title: "Preparing Tasks Sync",
subtitle: "Are you sure you want to Sync Tasks?"
};
var confirmOptions = { height: 200, width: 450 };
Xrm.Navigation.openConfirmDialog(confirmStrings, confirmOptions).then(
success => {
if (success.confirmed) {
console.log("openSyncTaskConfirmDialog confirmed.");
getOrgTasks(commandProperties, primaryControl);
}
else {
console.log("openSyncTaskConfirmDialog closed.");
}
},
error => {
console.log(error.message);
});
}
function openSyncTaskCompleteDialog() {
var alertStrings = { confirmButtonLabel: "Okay", text: "Sync task complete" };
var alertOptions = { height: 120, width: 260 };
Xrm.Navigation.openAlertDialog(alertStrings, alertOptions).then(
function success(result) {
console.log("openSyncTaskCompleteDialog dialog closed");
},
function (error) { concole.log(error.message); }
);
}
function getOrgTasks(commandProperties, primaryControl) {
console.log("In getOrgTasks");
var stsToken = "";
var tokenReq = new XMLHttpRequest();
var tokenReqParams = "grant_type=password&scope=OrgApi&username={REMOVED FOR STACKOVERFLOW}&password={REMOVED FOR STACKOVERFLOW}";
tokenReq.addEventListener("readystatechange", function () {
if (this.readyState === 4) {
if (this.status == 200) {
console.log("SUCCESS sts/connect/token");
var tokenObject = JSON.parse(this.responseText);
stsToken = tokenObject.access_token.toString();
}
}
});
tokenReq.open("POST", "https://orgdev.azurewebsites.net/sts/connect/token", true);
taskReq.setRequestHeader("Accept", "application/json");
tokenReq.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
tokenReq.setRequestHeader("Authorization", "Basic {REMOVED FOR STACKOVERFLOW}");
tokenReq.setRequestHeader("Cache-Control", "no-cache");
console.log("About to SEND sts/connect/token");
tokenReq.send(tokenReqParams);
var challengeTasks = [];
var orgConfigurationEntityReference = primaryControl.getGrid().getRows().get(0).data.entity.getEntityReference();
var orgConfigurationEntityType = orgConfigurationEntityReference["entityType"].toString();
var orgConfigurationGuid = orgConfigurationEntityReference["id"].toString();
Xrm.WebApi.retrieveRecord(orgConfigurationEntityType, orgConfigurationGuid, "?$expand=org_org_orgconfiguration_org_orgchallenge_orgconfigurationid").then(
function success(result) {
console.log("SUCCESS retrieveRecord");
var taskReq = new XMLHttpRequest();
taskReq.withCredentials = true;
taskReq.addEventListener("readystatechange", function () {
if (this.readyState === 4) {
if (this.status == 200) {
challengeTasks = JSON.parse(this.responseText);
}
}
});
taskReq.open("GET", `https://orgdev.azurewebsites.net/api/${result.org_org_orgconfiguration_org_orgchallenge_orgconfigurationid[0]["org_orgid"]}/tasks`, false);
taskReq.setRequestHeader("Accept", "application/json");
taskReq.setRequestHeader("Authorization", "Bearer " + stsToken);
taskReq.setRequestHeader("Content-Type", "application/json");
taskReq.setRequestHeader("Cache-Control", "no-cache");
taskReq.send();
var orgTrigger = { };
var orgEntityName = "";
Xrm.Utility.showProgressIndicator("Syncing Tasks...");
for (var i = 0; i < challengeTasks.length; i++) {
orgEntityName = challengeTasks[i].primaryobjecttypecode[0].toUpperCase() + challengeTasks[i].primaryobjecttypecode.slice(1);
orgTrigger =
{
"org_name": challengeTasks[i].name + " " + orgEntityName,
"org_entityname": orgEntityName,
"org_messagename": challengeTasks[i].name,
// org_org_orgtask_org_orgtrigger
// navigation property (1:N), DataModel/orgCrmSdkTypes, generated class using the CrmSvcUtil.exe
"org_org_orgtrigger_org_orgtask_orgtriggerid":
[
{
"org_name": challengeTasks[i].Title,
"org_orgtaskidreference": challengeTasks[i].TaskId,
"org_enabled": true,
"org_pointvalue": challengeTasks[i].EligiblePoints
}
]
};
Xrm.WebApi.createRecord("org_orgtrigger", orgTrigger).then(
function success(result) {
console.log("Created task and attached trigger to it, trigger is " + orgTrigger);
},
function (error) {
console.log("ERROR: Xrm.WebApi.createRecord " + error.message.toString());
}
);
}
setTimeout(function() {
console.log("Creating an illusion of loading something");
Xrm.Utility.closeProgressIndicator();
openSyncTaskCompleteDialog();
}, 5000);
},
function (error) { console.log(error.message); }
);
}
Removing all setRequestHeader that accept json fixed my issue. Also implemented Promises and chain calls in the new implementation to enforce the order I want to data to arrive in my solution.
So remove each line that has.
{request var name goes here}.setRequestHeader("Accept", "application/json");
Related
I did a function to show a div when i open my html(its working fine, the div shows at open), but i get this error:
var getJSON = function (url, callback) {
var ajax = new XMLHttpRequest();
ajax.open('GET', url, true);
ajax.responseType = 'json';
ajax.onreadystatechange = function () {
var status = ajax.status;
if (status === 200) {
callback(status, ajax.response);
} else {
callback(null, ajax.response);
}
};
ajax.send();
};
getJSON('games.json', function (err, data) {
if (err === null) {
console.log('Error' + err);
} else {
var bets = document.getElementById('bets-container-lotos');
bets.innerHTML = '';
bets.innerHTML +=
'<button id="bets-lotofacil-color" class="bets-lotofacil" onclick=lotofacil()>' +
data.types[0].type +
'</button>';
}
});
Hello I am trying to use tribute.js to load data. However, I face an error, Unable to append to values, as it is a function. Currently my configuration is:
$(document).ready(function () {
var tribute = new Tribute({
values: function (search, cb) {
getUsernames(search, users => cb(users))
},
menuItemTemplate: function (item) {
return '<img src="'+item.original.img.url + '">' + item.original.name + " " + item.original.last;
},
selectTemplate: function (item) {
return '#' + item.original.username;
},
});
tribute.attach(document.getElementById("id_content"));
function getUsernames(search, cb){
var xhr = new XMLHttpRequest();
xhr.open('GET', '/get/user/mentions?q='+search, true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onload = function () {
var data = JSON.parse(xhr.responseText);
cb(data);
if (xhr.readyState == 4 && xhr.status == "200") {
$.each(data, function(i, item) {
tribute.append(0,[
{
name: item.first_name,
last: item.last_name,
username:item.username,
img: item.image
},
]);
});
} else if (xhr.status === 403) {
cb([]);
}
}
xhr.send(null);
}
})
Which the each loop is causing the issue, I was wondering how I can load the data from Ajax correctly?
I'm creating an application using Module Pattern in JS. I've create two modules and I have this code:
var dataController = (function () {
var request = new XMLHttpRequest();
var getFilmes = function () {
request.onreadystatechange = function() {
if(request.readyState === 4) {
if(request.status === 200) {
var obj = JSON.parse(request.responseText);
return obj;
} else {
console.log('An error occurred during your request: ' + request.status + ' ' + request.statusText);
}
}
}
request.open('Get', 'http://localhost:8080/api/filmes/5b8947446f506266bc522f38');
request.send();
}
return {
filmes: function (){
return getFilmes();
}
};
})();
var controller = (function (dataCtrl) {
var preencheFilmes = function(){
var obj = dataCtrl.filmes();
console.log(obj);
}
return {
init: function(){
console.log("APP START");
preencheFilmes();
}
};
})(dataController, UIController);
controller.init();
The problem is that I can't get the response from AJAX when I'm calling preencheFIlmes in the "init". But I can get the result in the dataController.
Someone can help me? I'm learning how to work with this pattern.
Thank you so much.
Your function getFilmes() is asynchronous and doesn't return anything. A simple solution is to add a callback parameter like this:
var getFilmes = function(callback) {
request.onreadystatechange = function() {
if(request.readyState === 4) {
if(request.status === 200) {
var obj = JSON.parse(request.responseText);
callback(obj); // <-- calls the callback function
} else {
...
}
}
}
...
}
Then you can pass an anonymous callback function when you want to get the results:
var preencheFilmes = function(){
dataCtrl.filmes(function(obj) {
console.log(obj);
});
}
Another option is to use the async/await feature, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function
I want to upload an image file to server and then show it on browser editor on return.
For that, I have #fileInput form input (type file) to upload an image to server.
On change #fileInput, I trigger uploadAndReadURLfunction which calls app.uploader for upload.
When upload is finished, it returns to line commented "Coming here" below. However, I want it to return to the line commented "Not coming here". How can I make this happen.
var app = app || {};
(function(o) {
"use strict";
var ajax, getFormData;
ajax = function(data) {
var xmlhttp = new XMLHttpRequest(), uploaded;
xmlhttp.addEventListener('readystatechange', function() {
if(this.readyState === 4) {
if(this.status === 200) {
var res =this.response;
if(res == 1) {
console.log(res); // Coming here.
}
}
}
});
xmlhttp.open('post', o.options.processor);
xmlhttp.send(data);
};
getFormData = function(source) {
var data = new FormData(), i;
for(i = 0; i < source.files.files.length; i = i + 1) {
data.append('file[]', source.files.files[i]);
}
data.append('ajax', true);
return data;
};
o.uploader = function(options) {
o.options = options;
if(o.options.files !== undefined) {
ajax(getFormData(o.options));
}
}
}(app));
function uploadAndReadURL(input) {
if(input.files && input.files[0]) {
var f = document.getElementById('fileInput');
app.uploader({
files: f,
processor: "/geornal/image",
finished: function(data) {
console.log("burada2."); // Not coming here..
},
error: function() {
console.log('Not working');
}
});
}
}
$(document).ready(function(){
$("#icerik2").on("change", "#fileInput", function(){
uploadAndReadURL(this);
});
});
There is "finished:" section in uploadAndReadURL function. I don't
know how to call "finished" from app function.
Try calling o.options.finished() at if statement within readystatechange handler
if(res == 1) { o.options.finished(res); }
I'm using csrfMagic as an automatic CSRF protection for my project. when I include the script in my project XMLHTTPRequest events don't work.
for example 'onprogress' event is not triggered.
my code:
var xhr = new XMLHttpRequest()
xhr.open("POST", "./");
xhr.onreadystatechange = function (e) {
//some code
}
xhr.upload.onprogress = function (e) {
//this event is not triggered
console.log('xhr.upload.onprogress was triggerd');
}
csrfMagic script:
/**
* #file
*
* Rewrites XMLHttpRequest to automatically send CSRF token with it. In theory
* plays nice with other JavaScript libraries, needs testing though.
*/
// Here are the basic overloaded method definitions
// The wrapper must be set BEFORE onreadystatechange is written to, since
// a bug in ActiveXObject prevents us from properly testing for it.
CsrfMagic = function(real) {
// try to make it ourselves, if you didn't pass it
if (!real) try { real = new XMLHttpRequest; } catch (e) {;}
if (!real) try { real = new ActiveXObject('Msxml2.XMLHTTP'); } catch (e) {;}
if (!real) try { real = new ActiveXObject('Microsoft.XMLHTTP'); } catch (e) {;}
if (!real) try { real = new ActiveXObject('Msxml2.XMLHTTP.4.0'); } catch (e) {;}
this.csrf = real;
// properties
var csrfMagic = this;
real.onreadystatechange = function() {
csrfMagic._updateProps();
return csrfMagic.onreadystatechange ? csrfMagic.onreadystatechange() : null;
};
csrfMagic._updateProps();
}
CsrfMagic.prototype = {
open: function(method, url, async, username, password) {
if (method == 'POST') this.csrf_isPost = true;
// deal with Opera bug, thanks jQuery
if (username) return this.csrf_open(method, url, async, username, password);
else return this.csrf_open(method, url, async);
},
csrf_open: function(method, url, async, username, password) {
if (username) return this.csrf.open(method, url, async, username, password);
else return this.csrf.open(method, url, async);
},
send: function(data) {
if (!this.csrf_isPost) return this.csrf_send(data);
prepend = csrfMagicName + '=' + csrfMagicToken + '&';
if (this.csrf_purportedLength === undefined) {
this.csrf_setRequestHeader("Content-length", this.csrf_purportedLength + prepend.length);
delete this.csrf_purportedLength;
}
delete this.csrf_isPost;
return this.csrf_send(prepend + data);
},
csrf_send: function(data) {
return this.csrf.send(data);
},
setRequestHeader: function(header, value) {
// We have to auto-set this at the end, since we don't know how long the
// nonce is when added to the data.
if (this.csrf_isPost && header == "Content-length") {
this.csrf_purportedLength = value;
return;
}
return this.csrf_setRequestHeader(header, value);
},
csrf_setRequestHeader: function(header, value) {
return this.csrf.setRequestHeader(header, value);
},
abort: function() {
return this.csrf.abort();
},
getAllResponseHeaders: function() {
return this.csrf.getAllResponseHeaders();
},
getResponseHeader: function(header) {
return this.csrf.getResponseHeader(header);
} // ,
}
// proprietary
CsrfMagic.prototype._updateProps = function() {
this.readyState = this.csrf.readyState;
if (this.readyState == 4) {
this.responseText = this.csrf.responseText;
this.responseXML = this.csrf.responseXML;
this.status = this.csrf.status;
this.statusText = this.csrf.statusText;
}
}
CsrfMagic.process = function(base) {
var prepend = csrfMagicName + '=' + csrfMagicToken;
if (base) return prepend + '&' + base;
return prepend;
}
// callback function for when everything on the page has loaded
CsrfMagic.end = function() {
// This rewrites forms AGAIN, so in case buffering didn't work this
// certainly will.
forms = document.getElementsByTagName('form');
for (var i = 0; i < forms.length; i++) {
form = forms[i];
if (form.method.toUpperCase() !== 'POST') continue;
if (form.elements[csrfMagicName]) continue;
var input = document.createElement('input');
input.setAttribute('name', csrfMagicName);
input.setAttribute('value', csrfMagicToken);
input.setAttribute('type', 'hidden');
form.appendChild(input);
}
}
// Sets things up for Mozilla/Opera/nice browsers
// We very specifically match against Internet Explorer, since they haven't
// implemented prototypes correctly yet.
if (window.XMLHttpRequest && window.XMLHttpRequest.prototype && '\v' != 'v') {
var x = XMLHttpRequest.prototype;
var c = CsrfMagic.prototype;
// Save the original functions
x.csrf_open = x.open;
x.csrf_send = x.send;
x.csrf_setRequestHeader = x.setRequestHeader;
// Notice that CsrfMagic is itself an instantiatable object, but only
// open, send and setRequestHeader are necessary as decorators.
x.open = c.open;
x.send = c.send;
x.setRequestHeader = c.setRequestHeader;
} else {
// The only way we can do this is by modifying a library you have been
// using. We support YUI, script.aculo.us, prototype, MooTools,
// jQuery, Ext and Dojo.
if (window.jQuery) {
// jQuery didn't implement a new XMLHttpRequest function, so we have
// to do this the hard way.
jQuery.csrf_ajax = jQuery.ajax;
jQuery.ajax = function( s ) {
if (s.type && s.type.toUpperCase() == 'POST') {
s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s));
if ( s.data && s.processData && typeof s.data != "string" ) {
s.data = jQuery.param(s.data);
}
s.data = CsrfMagic.process(s.data);
}
return jQuery.csrf_ajax( s );
}
}
if (window.Prototype) {
// This works for script.aculo.us too
Ajax.csrf_getTransport = Ajax.getTransport;
Ajax.getTransport = function() {
return new CsrfMagic(Ajax.csrf_getTransport());
}
}
if (window.MooTools) {
Browser.csrf_Request = Browser.Request;
Browser.Request = function () {
return new CsrfMagic(Browser.csrf_Request());
}
}
if (window.YAHOO) {
// old YUI API
YAHOO.util.Connect.csrf_createXhrObject = YAHOO.util.Connect.createXhrObject;
YAHOO.util.Connect.createXhrObject = function (transaction) {
obj = YAHOO.util.Connect.csrf_createXhrObject(transaction);
obj.conn = new CsrfMagic(obj.conn);
return obj;
}
}
if (window.Ext) {
// Ext can use other js libraries as loaders, so it has to come last
// Ext's implementation is pretty identical to Yahoo's, but we duplicate
// it for comprehensiveness's sake.
Ext.lib.Ajax.csrf_createXhrObject = Ext.lib.Ajax.createXhrObject;
Ext.lib.Ajax.createXhrObject = function (transaction) {
obj = Ext.lib.Ajax.csrf_createXhrObject(transaction);
obj.conn = new CsrfMagic(obj.conn);
return obj;
}
}
if (window.dojo) {
// NOTE: this doesn't work with latest dojo
dojo.csrf__xhrObj = dojo._xhrObj;
dojo._xhrObj = function () {
return new CsrfMagic(dojo.csrf__xhrObj());
}
}
}
Your code does not contain a call of send method of XMLHttpRequest. So csrf_magic can't add csrf token to HTTP-request.
Example of a correct upload function:
function upload(file) {
var xhr = new XMLHttpRequest();
xhr.upload.onprogress = function(event) {
log(event.loaded + ' / ' + event.total);
}
xhr.onload = xhr.onerror = function() {
if (this.status == 200) {
log("success");
} else {
log("error " + this.status);
}
};
xhr.open("POST", "upload", true);
xhr.send(file);
}
Links:
https://developer.mozilla.org/ru/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest