Async Await is returning an undefined array in the function

My getJSON function is not returning the array I need. I have been attempting to use await/async, but it seems like there might be an error in my approach.

The methods .map and .filter are supposed to be synchronous, but even adding await does not seem to work as expected.

$(function() {
    $("#roll").click(async function() {
        var x = await fetchTreasure()
        chrome.extension.getBackgroundPage().console.log(x)
    });
});

function fetchTreasure() {
    var sizeValue = $('input[name=size]:checked').val();
    var crValue = $('input[name=challenge]:checked').val();
    var die = Math.floor((Math.random() * 100) + 1);
    var url = "";

    if (sizeValue == "individual") {
        url = chrome.runtime.getURL("treasure_individual.json");
    } else {
        url = chrome.runtime.getURL("treasure_horde.json");
    };
    $.getJSON(url, function(data) {
        var match = data.treasure.filter(function (e) {
            return e.cr == crValue;
        });
        for (i in match[0].roll) {
            var str = match[0].roll[i].d100;
            var arr = str.match(/([0-9]+)/g);
            var levels = $.map(arr, function (x) { 
                return parseInt(x, 10); 
            });

            if (die == levels[0] || die >= levels[0] && die <= levels[1]) {
                chrome.extension.getBackgroundPage().console.log(levels);
                return levels;
            } else {
                return die;
            }
        };
    });
};

Edit: I now realize that await still requires a Promise. However, I am still unable to achieve the desired result. I tried encapsulating the getJson function with a Promise, but the return for levels is still not working as intended.

function fetchTreasure() {
    var sizeValue = $('input[name=size]:checked').val();
    var crValue = $('input[name=challenge]:checked').val();
    var die = Math.floor((Math.random() * 100) + 1);
    var url = "";

    if (sizeValue == "individual") {
        url = chrome.runtime.getURL("treasure_individual.json");
    } else {
        url = chrome.runtime.getURL("treasure_horde.json");
    };

    return new Promise(resolve => {
        $.getJSON(url, function(data) {
            var match = data.treasure.filter(function (e) {
                return e.cr == crValue;
            });
            for (i in match[0].roll) {
                var str = match[0].roll[i].d100;
                var arr = str.match(/([0-9]+)/g);
                var levels = $.map(arr, function (x) { 
                    return parseInt(x, 10); 
                });

                if (die == levels[0] || die >= levels[0] && die <= levels[1]) {
                    //chrome.extension.getBackgroundPage().console.log(levels);
                    return levels;
                }
            };
        });
    });
};

Answer №1

To successfully return the promise, you should not introduce new Promise (which is considered an anti-pattern in this scenario). Instead, utilize the promise that jQuery already provides:

    return $.getJSON(url, function(data) {
//  ^^^^^^
       // .......
    }).promise();
//    ^^^^^^^^^^

Note: In your second attempt, you neglected to invoke resolve.

If you require specific data to be promised, then opt for chaining a then rather than relying on the callback of $.getJSON. It can be done as follows:

    return $.getJSON(url).then(function(data) {
//  ^^^^^^               ^^^^^^
       // .......
       return levels;
    });

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

Tips for combining JSON from two queries into a single array

$sql = "SELECT user_registration.user_id, user_registration.full_name, user_registration.username, user_profile.profile_picture FROM user_registration LEFT JOIN user_profile ON user_registra ...

Tips for filling in the values for the options in a select dropdown menu

Currently, I am facing a strange bug related to the select element. Whenever I open the dropdown, there is always a mysterious black option at the top. This is how my HTML looks like: This particular element is part of my test controller. <select ng- ...

Is it possible to utilize the logical OR operator with Strings as function arguments in JavaScript? It seems that the function may not evaluate the second string

When checking the backend using Vuex to conditionally render error messages, I utilize the getByTitle function below: const getByTitle = (memberTitle) => { return state.errors.find(e => e.meta.memberTitle === memberTitle) ?.content.error.tit ...

Deploying a React App to Github Pages Results in a Blank Screen

After successfully uploading a simple react app onto GitHub pages using gh-pages, I attempted to import the Shards dashboard project (https://github.com/DesignRevision/shards-dashboard-react) onto my GitHub page. Unfortunately, all I see is a blank page. ...

What is the reason behind the sudden "explosion" in this simulation?

Trying to create a simulation of a steerable vehicle, like a plane, hovercraft, or boat, in either a gas or liquid fluid (such as air or water). The JavaScript code is based on the 3D rigid body airplane simulator from Physics for Game Developers, adapted ...

angular controllers and directives using scope

I'm just starting to learn angular and I've run into a problem with the scope in my directive and controller. Take a look at my code: Controller: var myApp = angular.module('myApp', []); myApp.controller('testCtrl', fun ...

What is causing these TypeScript type assertions to go unnoticed?

While reviewing type assertions, I noticed something interesting about the last three variable assignments - they don't produce errors. It's perplexing because I thought I was trying to change 'helo' into 'hello', which should ...

No matter how many times I modified the code in the ReactDOM.render() method within my index.js file, the end result remained unchanged

When I ran npx create-react-app my-app, and then proceeded to cd my-app and npm start, a browser opened on localhost:3000. While looking at the index.js file, I noticed that the ReactDOM.render() method included the following code: ReactDOM.render( <Rea ...

Attempting to incorporate a factory within a restricted function

Just starting out with AngularJS and I have a question. Can I use a factory code (logger) inside a private function like the example below? I'm still working on understanding angular concepts. Thanks for your help: (function () { 'use strict ...

What is the best way to ensure buttons remain on the same line in Vue.js?

In a table, I have three buttons that are placed on top of each other when the data in the row is too long and expands the table. My goal is to keep these three buttons in one line regardless of the content length. <td class="text-xs-right"> <d ...

Is it possible to create a MongoDB query that can retrieve a specific number of documents from different types within a single collection?

If I have a collection named "pets" with three different types of animals: cat, dog, and bird What if there are 10 cats, 10 dogs, and 10 birds in the collection (30 documents total)? Can I create a query that retrieves 3 cats, 2 dogs, and 1 bird all at o ...

Having trouble accessing a gtlf file in an HTML document using Three.js

My goal is to create an interactive and clickable 3D image that I downloaded from Sketchfab using Three.js. I have carefully followed the guidelines provided by ChatGPT and have all the necessary scripts in my folder (GLTFLoader.js, main.js, OrbitControls. ...

jQuery plugin stops functioning properly following the use of the jQuery display block method

In my project, I am exploring the use of divs as tabs with jQuery. Within these divs, I also want to incorporate another jQuery plugin. Currently, I have manually created these div tabs using jQuery and set the default style for second and subsequent divs ...

How to extract information from a JavaScript object array in Node.js?

Currently, I am attempting to extract data from a JavaScript Object array by providing field names and then storing the data in an array. However, my current approach seems to be yielding incorrect results. Whenever I try to log the values stored in ' ...

Transform JSON data into an array of arrays

For my project, I am using the python SimpleHTTPWebserver to serve up various files, including a valid JSON file named "file.json". In my javascript front end, I need to interpret this JSON object as an array of arrays. For example: { "val1": 101, "va ...

The jQuery replacement should only be implemented on the new select box and not on the previous one

Let me illustrate the situation. I have a website and my aim is to gather information about the "Type of Business" for members on the site. I present all the current businesses that have been entered and allow users to choose one from the list. If a user w ...

Strategies for effectively managing multidimensional data in build properties for streamlined processing using foreach

Managing a list of users that need to be different for stage and production environments: user1: name: username1 password: password1 email: email1 roles: role1, role2 user2: name: username2 password: password2 email: email2 ...

Ways to implement a parallax effect by changing images within a specific div on scrolling with the mouse

First and foremost, thank you for taking the time to review my question. I am currently developing a website and I need to implement a vertical image transition effect within a selected division, similar to a parallax effect. Within this div, there are 3 ...

Utilizing Xcode to leverage JSON data and the POST method for verifying a user's credentials

Having recently started working with POST requests, I wrote a code snippet that collects a username and password input for validation purposes. The idea is simple - if the input is valid, it should return true, otherwise false. While most of my code seems ...

ui-router: Converting URL parameters

Is there a way to seamlessly transform URL parameters? Let me illustrate with a scenario. Our URL structure is like this: /shopping/nuts/:productId /shopping/berries/:productId /shopping/juice/:productId The products in our app, fetched from an API, may ...