Passing the output of a nested function back to its containing function in JavaScript within Dynamics CRM

Is it possible for the code below to send the boolean value from the inner function back to the parent function displayButton()? This parent function is triggered when a button in Dynamics CRM is clicked. The expected behavior is for the function to return a boolean value based on whether a case is selected and if that selected case is active or resolved.

   //function called when a button in MS CRM is clicked
    function displayButton()
    {
        var Obj = parent.Xrm.Page.getAttribute("regardingobjectid");
        var ObjValue = Obj.getValue();
        
        if (ObjValue == null)
            return false;

        var EntityType = ObjValue[0].entityType;
        var Guid = ObjValue[0].id;
        var id = Guid.slice(1, -1);

        if (EntityType == "incident")
        {
            var req = new XMLHttpRequest();
            req.open("GET", parent.Xrm.Page.context.getClientUrl() + "/api/data/v8.2/incidents(" + id + ")?$select=statecode", 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)
                    {
                        debugger;
                        var result = JSON.parse(this.response);
                        
                        var statecode = result["statecode"];
                        var statecode_formatted = result["<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="abd8dfcadfcec8c4cfceebe4efcadfca85e8c4c6c6dec5c2dfd285efc2d8dbc7cad285fd9a85edc4d9c6cadfdfcecffdcac7dece">[email protected]</a>"];
                        
                        if (statecode_formatted == "Active") {
                            return true;
                        }
                        else if (statecode_formatted == "Resolved")
                            return false;
                        else {
                            return false;
                        }
                    }
                    else
                    {
                        parent.Xrm.Utility.alertDialog("Zero");
                    }
                }
            };
            req.send();

        }
        else {
            return false;
        }
    }

Answer №1

It is essential to handle the value returned by your asynchronous XmlHttpRequest properly. One way to do this is to place your logic within the if (this.status === 200) scope or utilize a callback function.

Your use of the true parameter makes your XMLHttpRequest asynchronous, as shown in the following line:

req.open("GET", parent.Xrm.Page.context.getClientUrl() + "/api/data/v8.2/incidents(" + id + ")?$select=statecode", true);

To implement a callback function, it's recommended to separate your code into two functions:

function getCaseState(id, callback) {
    // XMLHttpRequest code here
}

Call the getCaseState function with the incident ID and a callback function like so:

// Function called on button click
function displayButton() {
    // Logic to retrieve relevant information
    if (entityType == "incident") {
        getCaseState(regardingId, function(state) {
            var isActive = state === "Active";

            if (isActive) {
                // Additional actions for active case
            }
        });
    }
}

It's also suggested to name the anonymous function provided in the callback for better organization of your code.

Answer №2

Simply put, the answer is a resounding No. The function inside is defined but never called within the code block. As a result, it will not be executed and no value will be returned.

If you want to learn more about functions in JavaScript, you might consider exploring this resource: https://www.w3schools.com/js/js_function_definition.asp

Answer №3

It seems like there is an issue with the amount of code you have included here. Remember, on Stack Overflow it's best to provide a Minimal, Complete, and Verifiable example. To address your current situation without making significant changes to your code, one approach would be to switch your request to synchronous as previously advised and assign the result to a variable declared outside of the callback function. Here's a proposed solution:

function displayButton(){
    var result = false; // or true, depending on your default requirement
    //some code...
    //change to synchronous request!!

    var req = new XMLHttpRequest();
    req.open("GET", parent.Xrm.Page.context.getClientUrl() + "/api/data/v8.2/incidents(" + id + ")?$select=statecode", false);
    //...
    req.onreadystatechange = function () {
         if (this.readyState === 4) {
             req.onreadystatechange = null;
             if (this.status === 200) {
                  // skipping additional code for brevity
                  //...
                  //...
                  if (statecode_formatted == "Active") {
                        result = true;
                    }
                    else if (statecode_formatted == "Resolved")
                        result = false;
                    else {
                        result = false;
                  }
             }
         }
     };
     req.send();

     return result;       
}

To avoid modifying your entire code block due to its length, consider moving your calling function to a separate function with a callback mechanism. Within this callback, update the value of "result". The use of callbacks ensures that the function runs synchronously, allowing it to return the correct "result" value.

Answer №4

Your XMLHttpRequest is operating asynchronously in this scenario. Therefore, you won't be able to retrieve the response immediately, resulting in a delay in execution.

To address this issue, I implemented the following solution:

setTimeout(function () {

  },550);

You may want to try the following approach:

The modification I made was separating the XMLHttpRequest into a dedicated function called getResult(id), which is then invoked from the parent function displayButton().

Instead of directly returning a value from the child function, I store the boolean result in a global variable named boolValue.

In the parent function, before returning a value, I introduce a 550-millisecond delay to ensure that the asynchronous execution completes.

Below is the code snippet illustrating this implementation:

Parent function

var boolValue;

// Function triggered upon clicking a button in MS CRM.
function displayButton() {
    var Obj = parent.Xrm.Page.getAttribute("regardingobjectid");
    var ObjValue = Obj.getValue();

    if (ObjValue == null)
        return false;

    var EntityType = ObjValue[0].entityType;
    var Guid = ObjValue[0].id;
    var id = Guid.slice(1, -1);

    if (EntityType == "incident") {
        getResult(id);

        setTimeout(function () {
            if(boolValue == true || boolValue == false)
            {
                return boolValue;
            }
        }, 550);

    }
    else {
        return false;
    }


}

Child function

function getResult(id)
{
    var req = new XMLHttpRequest();
    req.open("GET", parent.Xrm.Page.context.getClientUrl() + "/api/data/v8.2/incidents(" + id + ")?$select=statecode", 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 statecode = result["statecode"];
                
                // Check if the selected case is active or resolved.
                var statecode_formatted = result["<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="83f0f7e2f7e6e0ece7e6c3ccc7e2f7e2adc0eceeeef6edeaf7faadc7eaf0f3efe2fa_add56deeeaff9dfdea5eeebe4e5">[email protected]</a>"];
                if (statecode_formatted == "Active") {
                    boolValue = true;
                }
                else if (statecode_formatted == "Resolved")
                    boolValue = false;
                else {
                    boolValue = false;
                }
            }
            else {
                parent.Xrm.Utility.alertDialog("Zero");
            }
        }
    };
    req.send();
}

This methodology successfully resolved the issue for me.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is preventing me from being able to spyOn() specific functions within an injected service?

Currently, I am in the process of testing a component that involves calling multiple services. To simulate fake function calls, I have been injecting services and utilizing spyOn(). However, I encountered an issue where calling a specific function on one ...

Get a section of a website using JavaScript

My website has a large amount of data that causes it to load slowly. Within this site, there is a table displaying all the information. I am looking for a way to allow users to download the content of the table without reloading the entire page and proces ...

Tips for merging two JSON files to create a single associative array

How can I merge two similar JSON files in JavaScript, where elements from each are combined into a new associative array in a specific pattern? For example: var JSON1 = {'Item 1':123, 'Item 2':234, 'Item 3': 345} var JSON2 = ...

Top recommendation for parsing a single record from a JSON array

Currently I am fetching the result of a REST method (observable) which typically contains only one element. Although my code is functional and displaying the data, I keep getting an ERROR message in the browser console saying TypeError: Cannot read propert ...

Modifying background with JavaScript and AJAX技术

I currently have a table structured like the following; <table style="width: 100%; border: solid 1px #666600; min-width: 800px" cellpadding="0" cellspacing="0"> <tr> <td id="aaa">&nbsp;</td> ... Using jQuery's ajax functi ...

Condense third-party JavaScript libraries

Currently, I am in the process of consolidating a single vendor.min.js file in order to minimize the number of external files being loaded. To accomplish this, I have created the following gulp task: gulp.task('vendor-bundle', function() { gulp ...

Adjust the JavaScript variable upon pressing the "c" key

I'm trying to figure out how I can toggle the value of variable x in JavaScript when the key "c" is pressed. Specifically, I want x to change from 0 to 1 when "c" is pressed and revert back to 0 when it's released. I have already defined and name ...

The content on Twitter Bootstrap remains consistent

While using Twitter Bootstrap modals for updating contacts, I encountered some issues. The modal consistently displays the information of the first contact, whereas when displaying the information outside the modal, everything appears correctly. <?php ...

Looking to set a cursor style on a table row with JavaScript?

let table = document.getElementById(TABLE_NAME); let nextRow = table.tBodies[0].rows.length; row.setAttribute('style', "cursor: pointer;"); I am trying to implement a double click event on a table row, which is working as expected in most ...

Encountered a problem when attempting to upload files to AWS S3 using React and React AWS S3

One issue I'm facing is receiving a strange response when trying to perform a put operation in my bucket. I am utilizing the react-aws-s3 package which only requires the bucket name, user keys, and region in its configuration. It's puzzling as t ...

Setting a null image file in PHP after a successful AJAX operation can be accomplished by simply updating the

In my current project, I am working with Ajax and PHP. Upon clicking the post button, the message value gets removed using $("#message").val("") after a successful Ajax response (data insertion into the database via PHP and Ajax). Howev ...

Modifying an object's value before pushing it into an array in JavaScript

I've been struggling to find the right keyword to search for my issue. I've spent hours trying to figure out what's wrong, but it seems like a simple case of pushing an object into an array. The problem arises when I try to log the values of ...

Is it possible to integrate the Firestore npm library into my Express application?

Recently, I created my own library to act as a nosql database on my node.js web server in place of mongodb. I came across this interesting quote: Applications that use Google's Server SDKs should not be used in end-user environments, such as on pho ...

The error message appeared as a result of the bluebird and mongoose combination: TypeError: .create(...).then(...).nodeify is

Recently, I encountered an issue while attempting to integrate bluebird with mongoose. Here's the scenario: I wrote some test code using bluebird without incorporating mongoose, and it worked perfectly. The code looked something like this: A().then( ...

Discovering the Essence of AngularJS Test Runner: Unraveling the

I recently started learning Angular JS and decided to follow the tutorial here. I've encountered a roadblock in step 8 where I need to write a test to check if the thumbnail images are being displayed. The concept behind it is simple. There is a JSON ...

Merging HTML Array with jQuery

I am working with input fields of type text in the following code snippet: <input type="text" minlength="1" maxlength="1" class="myinputs" name="myinputs[]" > <input type="text" minlength="1" maxlength="1" class="myinputs" name="myinputs[]" > ...

Interactive feature: Div partially revealed, slides up upon image click

Here's a unique request - I'm trying to create an effect where a div slides up from the bottom of the screen when someone clicks on an image. To give you a better idea, think of the Windows desktop: when you click on the start menu icon, instead ...

Learn how to efficiently execute a function multiple times using pure JavaScript

I am trying to create a tabbed content functionality with multiple elements. How can I utilize the same function for various elements declared in a variable? For example, I want to clone the parent div.tabs element with similar content but different ids an ...

Another option instead of using `overflow: hidden` that won't cut off part of a character

My calculator display limits the numbers shown using the CSS property overflow: hidden. However, I don't want it to clip characters in half, which is currently happening. Mozilla suggests using text-overflow: '';, but this isn't widely ...

tips for accessing data from an external json file

[ ["timestamp","bfx_l","bfx_h","bfx_bv","bfx_b_s","bfx_b_l","bfx_s_s","bfx_s_s","okc_bv" ], ["0","225.25","225.25","225.63248","","","","","224.32" ], ["1","225.25","225.25","225.63248","","","","","224.32" ], ["2","225.25","225.25","225.63527", ...