Enhancing TypeScript - Managing Variables within Namespace/Scope

Why is the console.log inside the function correctly logging the object, but after the function returns it logs undefined, failing to update the variable?

In addition, when using this within testNameSpace, it returns window. Why is that?

namespace testNameSpace {

    let settings: any;

    function dtJSONLoad() {
        let xobj = new XMLHttpRequest();
        xobj.overrideMimeType("application/json");
        xobj.open('GET', './js/file.json', true);
        xobj.onreadystatechange = function () {
            if (xobj.readyState == 4) {
                let response = xobj.responseText;
                settings = JSON.parse(response);
                console.log(settings);
            }
        };
        xobj.send(null);
    }

    dtJSONLoad();
    console.log(settings);

}

The first console log outputs 'undefined'

The second console log shows the returned object

Answer №1

Two common issues frequently discussed on SO (especially those tagged with TypeScript) are presenting themselves to you.

The first problem arises when you perform an asynchronous operation like so:

dtJSONLoad();
console.log(settings);

Your console.log statement is running before the completion of the dtJSONLoad, resulting in the settings variable being undefined.
The second console.log reflects the true value upon the async operation's completion.

The issue also involves the scope of this:
When assigning a function to xobj.onreadystatechange, that function does not correspond to the current this, causing it to point to the Window object upon execution.
There are two ways to address this:

(1) Employ an arrow function to retain the existing scope of this:

xobj.onreadystatechange =  () => {
    // ...
};

(2) Utilize the Function.prototype.bind method:

xobj.onreadystatechange =  function () {
    // ...
}.bind(this);

Edit

In a namespace, the concept of this doesn't apply due to its compilation into javascript.
For instance, consider this scenario:

namespace mynamespace {
    console.log(this); // Error: 'this' cannot be referenced in a module or namespace body
}

This results in:

var mynamespace;
(function (mynamespace) {
    console.log(this);
})(mynamespace || (mynamespace = {}));

An equivalent method would involve:

function fn() {
    console.log(this);
}

In both cases, this points to the Window object.

If you modify it as follows:

namespace mynamespace {
    export function fn() {
        console.log(this);
    }
}

mynamespace.fn();

You'll observe the output as: Object {}, which is accurate because the fn resides within mynamespace.
Here's how it appears in JavaScript:

var mynamespace;
(function (mynamespace) {
    function fn() {
        console.log(this);
    }
    mynamespace.fn = fn;
})(mynamespace || (mynamespace = {}));

Answer №2

Upon initial logging, the data is not yet present.

The data only appears during the callback on the second attempt, shortly after the request is initiated for the first time.

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

Troubleshooting problem in Vercel with Next.js 13 application - encountering "Module not found" error

Encountering a deployment issue with my Next.js 13 application on Vercel. I recently implemented the Parallel Routes feature of Next in my codebase. While pushing the changes to create a new pull request on GitHub, the branch's deployment on Vercel is ...

Removing HTML DOM elements from a string using JavaScript: A step-by-step guide

Hey there, I'm currently working on my angular application. When it comes to inserting the first 100 characters of content into the "description" meta tag for Facebook sharing, I've run into an issue. The description ends up including the HTML el ...

Why isn't this code for hiding the animation and displaying it not functioning properly?

Why isn't this animation from display none to block working properly? The initial code appears as follows, and it functions correctly: $(".box_outer").stop().animate({top: '25px' , opacity: 1}, 100); When I add display: none; to the class ...

The conditional statement does not align with my Regular Expression

I'm experiencing a peculiar issue with my regular expression matching in the code snippet provided. Even though the alert confirms a match between the strings, the if statement fails to trigger. Any insights on why this might be happening? Appreciate ...

Retrieving data from an array using an AJAX request function

I've been attempting to utilize an AJAX call to update a series of image elements on a webpage. The array containing the elements to update is populated with URLs fetched from a PHP page via AJAX. The issue I'm encountering with the code provide ...

Creating dynamic bar chart visuals using Morris.js with JSON responses

Utilizing the morris.js library, I am extracting and plotting bar charts from data retrieved through a webservice. Issue: The format of my webservice URL is as follows: http://localhost:9999/hellowebservice/search?select=* I populate the select query ...

What could be causing my data to shift after refreshing in Firefox with the F5 key?

My webpage has four tables, each containing rows with two text boxes filled with numeric values from the server. However, something peculiar occurs. When I add data to a row, let's say row 1, and then refresh the page, two values are mysteriously mov ...

Troubleshooting a dysfunctional Vue.js component

I am currently facing a challenge in getting components to function properly. Interestingly, without the component, everything seems to be working fine (as per the commented code). Here is my HTML snippet: <strong>Total Price:</strong> <sp ...

Encoding JSON data with various structures using JSONEncoder

Hey there, I have a collection of JSON Packets as shown below: { "data" : { "lng" : 36.159999999999997, "lat" : 50.359999999999999, "accuracy" : 5 }, "header" : { "type" : "loc" } } and also this one: { "data" : { "time" : ...

Updating MongoDB with an unknown object can be a challenging task, but there

In my current project, I have set up a Mongoose model as follows: const userSchema = new mongoose.Schema({ userID: { type: String, require: true, unique: true }, username: { type: String }, serverID: { type: String, require: true }, roles: ...

Vue.js: The Power of Manipulating Strings

Why is the filter method not working with this.userId, but it is working with the hard-coded value "admin"? How can I resolve this issue? computed: { UidMessages: function() { return this.Messages.filter(function(m) { return m ...

Tips for streaming AWS Lambda response in nodeJS

I have a serverless AWS Lambda function that I need to trigger from my Node.js application and stream the response back to the client. Despite searching through the official documentation, I cannot find a straightforward way to achieve this. I am hoping to ...

Expo constants failing to load on web due to unresolved manifest object issue

When setting up Firebase Auth in my expo app (using Google Auth), I needed to store my firebase variables in a .env file containing API_KEYS, AuthDomain, and more. To access these environment variables, I utilized expo constants in my firebase.ts file. Ini ...

What is the fastest way to invoke the driver.quit() method in Selenium?

Is there a way to force close the browser immediately instead of waiting for it to complete loading before calling driver.quit()? ...

Is there a way to retrieve values from TextFields and Select elements by simply clicking on a button?

I am currently working on a project using react, redux, and material ui. I need to retrieve data from a TextField in order to make an order. The code snippet below showcases my current implementation: <Select value={product.color_set[0].title}> { ...

Highchart displays text centrally on legend hover

I am struggling with the code provided here. My goal is to make text appear in the center of the donut chart when hovering over the legend. Similar to how it works when hovering over a single piece of the donut chart. var chart = new Highcharts.Chart ...

Creating a 2D Image Display in three.js

I'm facing a challenge with my threejs project. My goal is to have a 2D image appear on the screen when I press a key. I've done some research but haven't been able to find a solution that works for me. The methods I've tried either don ...

Every time I try to install create-react-app, I keep encountering a frustrating 'network Socket timeout' error

$ npx create-react-app amazon-clone npm WARN config global `--global`, `--local` are deprecated. Use `--location=global` instead. Creating a new React app in D:\js\faceboom. npm WARN config global `--global`, `--local` are deprecated. ...

NextJS version 14 now throws an error when attempting to use FormData that is

const FormPage = () => { const [categories, setCategories] = useState([]); const [productName, setProductName] = useState(); const [categoryID, setCategoryID] = useState(); const [productDescription, setProductDescription] = useState() ...

Failing to include a valid string in the path will result in an

Within my node API, I have a function that updates the email address array for either a contact or a farm. The concept is the same, but the difference lies in where the array is located: in farms it's within Records.emails, and in Contacts it's s ...