The failure of the ajax call to encapsulate is likely due to issues with object visibility

Having some trouble with a piece of code meant to run smoothly on Firefox 3.6. The issue arises when the variable this.xmlhttp, defined in STEP2 and used in STEP3, seems to be operating in different variable environments. Even though I expect the two usages in server_request and callback_function to refer to the same member object in the query_request_manager superobject that is defined below. Interestingly, a similar piece of code without asynchronous callbacks functions as intended during server response.

function Generic_server_request(server_location, server_file, client_callback_function)
{
    this.server_location = server_location;
    this.server_file = server_file;
    this.query_parameters = "";
    this.client_callback_function = client_callback_function;
    this.xmlhttp = undefined;
} // STEP1 initializes xmlhttp as undefined

Generic_server_request.prototype.callback_function = function ()
{
    if (this.xmlhttp.readyState === 4 // STEP3 ERROR xmlhttp is undefined
    // I expected it to reference the object defined at STEP2
    // but according to Firebug, it's not working as anticipated
    // Conversely, similar code without asynchronous callbacks
    // operates as expected: no issues with undefined variables
    && this.xmlhttp.status === 200)
    {
        this.client_callback_function(
        this.xmlhttp.responseText);
    }
    else if (this.xmlhttp.status !== 200 || (this.xmlhttp.status === 200 && this.xmlhttp.readyState !== 2 && this.xmlhttp.readyState !== 3))
    {
        alert("readystate " + this.xmlhttp.readyState + " status " + this.xmlhttp.status);
    }
};

Generic_server_request.prototype.server_request = function ()
{
    this.xmlhttp = new XMLHttpRequest(); // STEP2 defines xmlhttp for use
    this.xmlhttp.onreadystatechange = this.callback_function; // server callback to prototype.callback
    this.xmlhttp.open("GET", this.server_location + this.server_file + this.query_parameters, true);
    this.xmlhttp.send();
};

Generic_server_request.prototype.set_query_parameters = function (query_parameters)
{
    this.query_parameters = query_parameters;
};

var query_request_manager;

function do_querry()
{
    server_querry("test");
}

function server_querry(input)
{
    if (query_request_manager === undefined)
    {
        query_request_manager = new Generic_server_request( // defining the object
        "http://localhost/cgi-bin/", "querry_handler.php", status_text);
    }
    query_request_manager.set_query_parameters("?input=" + input);
    query_request_manager.server_request();
} // utilizing the object

// end of javascript

<input type="button" value="Enter" onclick="do_querry();" />

Answer №1

The main concern lies with the way this task is being approached:

By setting <strong>this.xmlhttp.onreadystatechange</strong> to <strong>this.callback_function</strong>, the function associated with <strong>this.callback_function</strong> is being bound to <strong>onreadystatechange</strong>. However, the issue arises when the scope is not properly bound to <strong>query_request_manager</strong>, resulting in it being executed under the global scope rather than the desired object's scope. To address this, employing a delegate function is recommended:
this.xmlhttp.onreadystatechange = (function () {
    var me = this;
    return function () {
       return me.callback_function.apply(me, arguments);
    }
}).call(this);

Answer №2

Give this a try:

var Custom_request = function(server_location, server_file, client_callback_function){
  this.server_location = server_location;
  this.server_file = server_file;
  this.query_parameters = "";
  this.client_callback_function = client_callback_function;
  this.xmlhttp = undefined; // Start with xmlhttp as undefined
}

Custom_request.prototype.callback_function = function(){
  if(this.xmlhttp.readyState === 4 && this.xmlhttp.status === 200){ // Check xmlhttp status and ready state
    this.client_callback_function(this.xmlhttp.responseText);
  } else if(this.xmlhttp.status!==200 || (this.xmlhttp.status===200 && this.xmlhttp.readyState!==2 && this.xmlhttp.readyState!==3)){
    alert("ReadyState " + this.xmlhttp.readyState + " Status " + this.xmlhttp.status);
  }
};
Custom_request.prototype.server_request=function(){
  this.xmlhttp = new XMLHttpRequest(); // Define xmlhttp for use
  this.xmlhttp.onreadystatechange = this.callback_function; 
  this.xmlhttp.open("GET", this.server_location + this.server_file + this.query_parameters, true);
  this.xmlhttp.send();
};
Custom_request.prototype.set_query_parameters = function(query_parameters){
  this.query_parameters = query_parameters;
};
var custom_request_manager; 

function execute_query(){
  make_server_request("test");
}
function make_server_request(input){
  if(custom_request_manager === undefined){
    custom_request_manager = new Custom_request("http://localhost/cgi-bin/", "handler.php", output_text);
  }
  custom_request_manager.set_query_parameters("?input=" + input);
  custom_request_manager.server_request();
}


<input type="button" value="Enter" onclick="execute_query();" />

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

Exploring new possibilities in ChartJS with the use of multiple Y

I have successfully created a line chart using Chart.js with two datasets, each having its own Y scale and axis. The code for my datasets and options is as follows: datasets: [{ fill:false, label: 'Heat', yAxisID: "y-axis-1", da ...

Guide on transforming a select dropdown into a ul dropdown

I am attempting to transform my select dropdown menu into an unordered list (ul) in order to create a bootstrap button that will display the ul, allowing the list items to function as options. <select id="sortField" onchange="refreshPage('{$pageBa ...

Click event in safari failing to trigger on iPhone

Issue with click event on mobile Safari browser when using an iPhone In a React class component, the click event listener is triggered on the window when opening the menu. This functionality works correctly everywhere except for iPhone Safari. toggleMenu ...

Using AJAX to process PHP form submissions

Here is the script in the head of my document: <script> $(function () { $('form#ratingsform').on('submit', function (e) { $.ajax({ type: 'post', url: '/dev/scripts/ratevideo_vibrary.php& ...

integrating a ui-bootstrap modal in a sidebar using angularjs

I recently utilized the modal example from https://angular-ui.github.io/bootstrap/ and everything worked perfectly. By using the code snippet below, I was able to successfully open the modal as shown in the example: $scope.open = function (size) { v ...

The process of updating the value of an element in local storage with JavaScript

Most of the time we have an object stored in our localStorage. let car = { brand: "Tesla", model: "Model S" }; localStorage.setItem("car", JSON.stringify(car)); https://i.sstatic.net/qWEkE.png I am now eager to update the value of "model". H ...

What are the best ways to incorporate mistakes into my JavaScript mortgage calculator?

I am struggling to set up my calculator so that it triggers an error message if the APR goes over 25% or falls below 0. Also, the Loan Term should be greater than 0 and less than or equal to 40, otherwise display an error message. I have attempted differen ...

Tips for showcasing an item with the chosen value in a dropdown menu

Below is the object I created: export default { data() { return { language: { "en": { welcomeMsg: "Welcome to New York City" }, "de": { ...

What steps can I take to prevent the [Vue warn]: Potential infinite update loop detected in a component render function issue in my VueJS project?

What are some tips to prevent an infinite update loop in a component render function using VUEJS? I have created a simple show password button with the following structure: <div class="mt-4 switchContainerGenPassword"> <div class="switchGene ...

Building a conditional statement in React based on the URL path: A beginner's guide

I want to incorporate a transparent menu specifically on the homepage. How should I go about this? I've established a constant named isHomePage and now I need to set a URL (the index.tsx) to define this constant. function MyApp({ Component, pageProps ...

Transforming numbers into arrays in JavaScript/TypeScript for Angular 7

What is the best way to convert the number 10 into an array in JavaScript? expected output: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] OR How can I transform the number 10 into the number of items within an array using JavaScript? ...

AntDesign is throwing an error stating that resetFields is not a function when using

I'm facing an issue with resetting the fields in my form. The form allows users to add more forms, and so on... Upon successful validation, I want to save the data in my DB and store AND reset all input fields in the form. Unfortunately, I'm un ...

Automatically switch to the designated tab depending on the URL

Is it possible to automatically activate a specific tab based on the URL structure if my tabs are configured in this way? I am looking for a solution where a link on www.example1.com/notabs.html will redirect to www.example2.com/tabs.html This particular ...

Using different CSS classes interchangeably in AngularJS

Imagine you have a list with an unknown number of items, ranging from one to potentially dozens. You want to display five CSS classes in a regular alternating pattern. What would be the most effective approach to achieve this? Here is some sample HTML cod ...

Generate a PDF document on the user's device

Is there a way for me to trigger the print command on a PDF file without relying on Adobe PDF viewer's print button? I'm interested in using a separate event instead of the print button within the PDF viewer. Is this achievable? ...

Unable to view image when using material-ui CardMedia component

Hello, I've encountered a problem with rendering an image in my application. Let me explain the issue in a simplified manner. So, I have a card component (MyCardComponent) where I need to pass a string prop containing the image file location. The goa ...

Encountering a Next.js prerendering issue when using getStaticPaths

I am currently developing a Next.js application. Here is the structure of my files: cpanearme -components -listitem.js -pages -home -index.js -firm -[id].js Below is the code for a list item that redirects to the dynamic rout ...

Stop the setTimeout function after redirecting in the controller

I am experiencing an issue with my AJAX call as it keeps triggering my controller repeatedly. AJAX function <script type="text/javascript> var stopTime =0; var scoreCheck = function () { $.ajax({ url: "<?php echo 'http:// ...

ReactJs: Tweaking Padding in Material-UI Table

After inheriting this fullstack app, I noticed that the original developers had incorporated a component to generate tables for the webpage. However, there is an issue with the padding on all the cells being too large. Through Chrome developer tools, I di ...

Guide on inserting HTML text box form input into Express route parameter

I'm currently working on implementing a feature that allows users to search through my mongo database using an endpoint structured like this: app.get('/search/:input', function(req, res){ console.log(`get request to: /members/${req.params ...