BAD REQUEST When making an AJAX CALL: This.readyState is undefined - javascript

I wrote a function that fetches the guid of a lookup field and uses that to make an AJAX call. This is the the call that I made:
fetchOptionSet: function (executionContext) {
var formContext = executionContext.getFormContext(); //get form context
var client = Xrm.Page.context.getClientUrl(); //get client url
var childId = formContext.getAttribute("new_childid").getValue()[0].id;
var child = childId.replace(/[{}]/g, "");
var contract;
var req = new XMLHttpRequest();
req.open("GET", client + `/api/data/v8.2/new_childallergieses(${child})?$select=_new_childid_value`, true);
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("Prefer", "odata.include-annotations=\"*\"");
req.onreadystatechange = function () {
if (this.readyState === 4) {
req.onreadystatechange = null;
if (this.status === 200) {
var result = JSON.parse(this.response);
var _new_childid_value = result["_new_childid_value"];
contract = _new_childid_value.replace(/[{}]/g, "");
} else {
Xrm.Utility.alertDialog(this.statusText);
}
}
};
req.send();
However, I get a bad request every time that the script runs. I need the guid returned by the call (contractid) to make another ajax call! The uri is fine,I tested the link in the browser and it returns the contractid that I want.

First issue Bad request can be solved by replacing GUID value childId for any {}.
Second issue, this is Ajax call which is asynchronous by mentioning true in req.open, hence you may have some other issue with request uri. That’s why readyState is undefined.
Try this. Take your uri & paste in browser address bar to see any clear error.
http://test.crm.dynamics.com/api/data/v8.2/new_childallergieses(guid)?$select=_new_childid_value

Changed from Asychronous to Sychronous and all of a sudden it worked!
var path_one = Xrm.Page.context.getClientUrl() + "/api/data/v8.2/new_childallergieses(" + child + ")?$select=_new_childid_value";
req.open("GET", path_one , false);
I did some investigating and realized that the function is set to execute on load, and sending an asynchronous call on load gives a bad request.

Related

Why is my XML Http request not executing anything?

I have a XML http requests but for some reason it doesn't work. It is supposed to check the number of friends the person has then if there aren't enough displayed you know, do all that stuff. And don't worry, I checked the database and all the sql, it removes/adds friends successfully but the problem is that the console says it executes it but the function doesn't do anything
Here is the function :
x = document.getElementsByClassName("numoffriends");
numoffriends = x.length;
var fullurl = "../backend/friends.php?numoffriends=" + numoffriends + "&loadfriends=true";
var request = new XMLHttpRequest();
request.open("GET", fullurl , false);
request.onload = function(){
if(request.status == 200){
let testdivvv = document.createElement("element");
testdivvv.innerHTML = this.responseText;
groupchat = document.getElementById("leftsmallbox");
groupchat.append(testdivvv);
}
}
request.send();
}
setInterval(loadfriends, 1500);
If it makes any difference there are also 4 other functions on the same timing i.e gets executed. I checked, there is indeed an object called leftsmallbox.
If you have any questions just ask, I'll be available for a while

How to call Actions from Javascript Microsoft Dynamics

I have a requirement to call a Action Process from Javascript.
My Action Accept 2 Input Parameters and 1 output Param. Below is the screenshot of my Action
I have a textField in my Form, and on it's onChange event I'm calling this CallAction Method. Below is the JavaScript
function CallAction() {
var actionName = "taqi_getPrice";
var actionParameters = {
"base": "USD",
"TotalPrice": "200"
};
var actionResponse = activateCustomAction(actionName, actionParameters);
}
function activateCustomAction(actionName, actionParams) {
var req = new XMLHttpRequest();
req.open("POST", Xrm.Page.context.getClientUrl() + "/api/data/v9.0/taqi_getPrice", false);
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.onreadystatechange = function () {
if (this.readyState === 4) {
req.onreadystatechange = null;
if (this.status === 200) {
var results = JSON.parse(this.response);
alert('Success');
} else {
alert('fail');
//Xrm.Utility.alertDialog(this.statusText);
console.log(this);
}
}
};
req.send(JSON.stringify(actionParams));
}
When running this script I'm getting the following error in chrome console
POST https://techgulf.crm4.dynamics.com/api/data/v9.0/taqi_getPrice 404
Sometime it also says
Request header field Access-Control-Allow-Headers is not allowed by Access-Control-Allow-Headers
Well I created Exact same Action as you mentioned in your screenshot, Except Entity I used is Account. I used below code to fire Action and it did worked for me without any issue and returned the value as expected.
May be for Testing you could provide static Guid and see how you get the result.
var parameters = {};
parameters.base = "123";
parameters.TotalPrice = "222";
var req = new XMLHttpRequest();
req.open("POST", Xrm.Page.context.getClientUrl() + "/api/data/v9.1/accounts(DC86C293-CA4F-E911-A82F-000D3A385A1C)/Microsoft.Dynamics.CRM.crmp_TestAction2", false);
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.onreadystatechange = function() {
if (this.readyState === 4) {
req.onreadystatechange = null;
if (this.status === 200) {
var results = JSON.parse(this.response);
} else {
Xrm.Utility.alertDialog(this.statusText);
}
}
};
req.send(JSON.stringify(parameters));
Change the below line
req.open("POST", Xrm.Page.context.getClientUrl() + "/api/data/v9.0/taqi_getPrice", false);
like this one below:
req.open("POST", Xrm.Page.context.getClientUrl() + "/api/data/v9.0/taqi_cars(" + Id + ")/Microsoft.Dynamics.CRM.taqi_getPrice", false);
Basically we need to pass name of the Entity Set with id of the record
followed by name of the action appended with Microsoft.Dynamics.CRM.
In case of global action, we just need the
Microsoft.Dynamics.CRM.<<ActionName>>.
Reference
Looks like you need a synchronous Action call execution (as you’re using false in req.open) otherwise you can use Xrm.WebApi.online.execute which is always Asynchronous. Read more

Bad request error when calling a custom action through Javascript

I created a custom action on CRM 365 which has one input parameter of type entity reference and it refers to the user entity, I tried to change the input parameter into another type and it works well. So I think the issue is in the way I pass the entity reference value, I tried to change it but I haven't had any luck so can someone tell me what is the wrong in the below code?
function CreateBlockHistory() {
var Id = Xrm.Page.data.entity.getId();
Id = Id.replace("{", "").replace("}", "");
var data = {
"BlockedBy": {
"ohd_blockedby": Xrm.Page.context.getUserId().replace("}", "").replace("{", ""),
"#odata.type": "Microsoft.Dynamics.CRM.systemuser"
}
};
var serverURL = window.parent.Xrm.Page.context.getClientUrl();
var req = new XMLHttpRequest();
req.open("POST", serverURL + "/api/data/v8.1/new_units(" + Id + ")/Microsoft.Dynamics.CRM.ohd_ActionTest", false);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.onreadystatechange = function () {
if (this.readyState == 4 /* request completed */) {
req.onreadystatechange = null;
if (this.status == 200 /* response ready */) {
var data = JSON.parse(this.response);
}
else {
var error = JSON.parse(this.response).error;
}
}
};
req.send(window.JSON.stringify(data));
}
To start with 400 Bad request - it is a very generic useless error, instead of relying on this - try to run the same snippet in browser console or CRM REST Builder by passing hardcoded guid parameters to see execution status. You can debug too
I see your XMLHttpRequest is running synchronous ( bool param as false), switch it to Async & see
Also I see you are getting Xrm context with mixed approach like window.parent sometimes & directly sometimes. window.JSON too. If this is executing in web resource not in any entity form then fix it appropriately
You can register a plugin on that custom action message, profile/debug & see for any clue

What does readyState ==1 means?

I am using this below function to fetch the product number for a particular productid.
function GetQuickCode(){
var material = Xrm.Page.getAttribute("one_materialid").getValue();
var id = material[0].id;
id=id.replace("{","").replace("}","");
var req = new XMLHttpRequest();
req.open("GET", Xrm.Page.context.getClientUrl() + "/api/data/v8.2/products("+id+")?$select=productnumber", true);
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("Prefer", "odata.include-annotations=\"*\"");
req.onreadystatechange = function () {
if (this.readyState === 4) {
req.onreadystatechange = null;
if (this.status === 200) {
var result = JSON.parse(this.response);
var productnumber = result["productnumber"];
Xrm.Page.getAttribute("one_quickcode").setValue(productnumber.Value);
} else {
Xrm.Utility.alertDialog(this.statusText);
}
}
};
req.send();
}
this function is returning readyState==1 which is why I am unable to find the value of product number. Also the response value does not contain anything. Can anyone tell me if I am wrong somewhere.
Try to debug your code in a few steps to find the problem.
First replace this line of code
req.open("GET", Xrm.Page.context.getClientUrl() + "/api/data/v8.2/products("+id+")?$select=productnumber", true);
by
var url= Xrm.Page.context.getClientUrl() + "/api/data/v8.2/products("+id+")?$select=productnumber";
console.log(url);
req.open("GET", url, true);
Does URL look correct?
Does it return correct result if you open directly in your browser?
If it works, you can continue further. If not, you need to fix the URL. You can start by removing parts from the end of the URL. Also, what is your CRM version? Is it 8.2 (Dynamics 365)?
Second, by using debug mode, inspect object this, especially attributes response and responseText, whether they contains some message.
Third, in F12 tool inspect the request and response. The tab is called Net or Network depending on browser. There can be many items. Clear the list before running your code. Look there what happened, what is returned for your request.

Navigate to URL with custom request headers in JavaScript

Question just like the title.
In command line, we can type:
curl -H "header_name: header_value" "http://example"
to navigate to http://example with a custom request header as shown above.
Q: If I need to write a JavaScript to do the same thing, how should I do?
var url = 'https://example';
var myRequest = new XMLHttpRequest();
myRequest.open('GET', url ,false);
myRequest.setRequestHeader('header-name','header-value');
myRequest.send();
I tried this code, there is no syntax error but the page didn't change. Hence, I don't really know if I modified the request header(s).
Here is how you can handle this:
var req = new XMLHttpRequest();
req.open('GET', 'http://example', true); //true means request will be async
req.onreadystatechange = function (aEvt) {
if (req.readyState == 4) {
if(req.status == 200)
//update your page here
//req.responseText - is your result html or whatever you send as a response
else
alert("Error loading page\n");
}
};
req.setRequestHeader('header_name', 'header_value');
req.send();

Categories