What could be causing this Javascript Array() to generate an array containing just a single element?

In my next js app, I have the following function:

export async function getServerSideProps(ctx) {
    const campaign = campaignInstance(ctx.params.address);
    const requestCount = await campaign.methods.getRequestsCount().call();
    
    console.log(requestCount);
    console.log(Array(requestCount).fill());

    // This is my current objective...
    // Since I can't retrieve a complete array of structs from
    // a Solidity smart contract, I am fetching each element individually.

    const requests = await Promise.all(
        Array(requestCount).fill().map((element, index) => {
            return campaign.methods.requests(index).call();
        })
    );

    return {
        props: {
            requests: JSON.stringify(requests),
            address: ctx.params.address
        }
    };
}

When I check my console, I see the following output:

4
[ undefined ]

At first glance, I expected to see an array with 4 undefined elements. The value of requestCount is clearly 4.

Answer №1

According to the insight shared by Sebastian, it appears that your requestCount variable is most likely a string rather than a number:

new Array(4).fill()
// Array(4) [ undefined, undefined, undefined, undefined ]

new Array("4").fill()
// Array(1) [ undefined ]

The behavior of the second constructor is significantly different from the first one. When using new Array(int), an Array with <int> empty slots is created. On the other hand, new Array(not-an-int) will create an array with the constructor arguments as content:

new Array(4)
// Array(4) [ <4 empty slots> ]

new Array("4")
// Array(1) ["4"]

Calling .fill() without any argument implies "replace the content for all elements with undefined". Since we have an array containing a single element (the string "4"), we end up with [undefined].

The key takeaway here is to always validate your inputs before passing them to functions or constructors that accept different argument types:

const requestCount = await campaign.methods.getRequestsCount().call();

// Validate the result before proceeding further:

const n = parseInt(requestCount);

if (isNaN(n)) {
  // Handle this scenario appropriately
}

else if (n > 0) {
  const mapped = [...Array(n)].map((_,i) => {
    // Process the index i
  });
}

Optimizing the "convenient syntax" using map can be achieved without creating an array and then discarding it immediately, by utilizing the array's stack functions:

// Note: Use let instead of const for n as it will be decremented to 0
let n = .....

...Check for bad values of n and return early...

const mapped = [];
while(n--) {
  // Use unshift() to push elements to the start of the array
  mapped.unshift(campaign.methods.requests(n).call());
}

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

Unraveling the Mysteries of Ajax Debugging

I am currently facing a perplexing issue with a program I created. Until recently, everything was functioning perfectly fine. However, at present, I am encountering initialization problems that have left me puzzled. From my understanding, it seems that the ...

Playing back an Audio object using JavaScript

I'm facing an issue with replaying an audio sound every time the game starts in my Cocos2d javascript code. The sound plays correctly the first time, but subsequent attempts to play it result in no sound being heard. Below is my code snippet: var my ...

variety of provider setups available in Angular

Trying to learn Angular from various online sources can be quite confusing, as different people use different patterns when writing functions. Can someone please explain the .provider concept in Angular? I have experimented with the .provider method using ...

ways to incorporate searching within JSON data using AJAX and jQuery in JavaScript

My search box needs to have JSON data appended into it. Below is the HTML code: <input type="search" id="merchantName" name="merchant" placeholder="enter merchant name"></input> I have JSON data containing merchant names that I want to appen ...

What is the best way to retrieve the value of a selected radio button with YUI?

Here is the structure of my radio buttons... <div id="test"> <input name="test1" value="a" type="radio"> <input name="test1" value="b" type="radio"> <input name="test1" value="c" type="radio"> </div> What is the best w ...

What are some ways to display unprocessed image data on a website using JavaScript?

I have an API endpoint that provides image files in raw data format. How can I display this image data on a website using the img tag or CSS background-image property, without utilizing canvas? One possible approach is shown below: $.get({ url: '/ ...

Utilizing JavaScript to dynamically resize an element within a slide as soon as the slider transitions to the following slide

RESOLVED! ISSUE FIXED! While working on my personal website using WordPress and the Smart Slider 3 plugin, I encountered a problem with the positioning and size of an element in the second slide. Despite finding a tutorial explaining how to manually trigg ...

Adding semi-colon in JavaScript with special comments by YUI Compressor

Our team recently implemented YUI Compressor (2.4.8) on our project and it's been performing well. However, we encountered an unexpected issue while minifying JavaScript files that contain special comments. It appears that YUI Compressor is automatic ...

How can I properly choose distinct values for an individual attribute from a JavaScript array containing objects?

Let's imagine a scenario with an array of JavaScript objects like this: var data = [ {category : "root", type: "qqqqq", value1: "aaaaa", value2: "zzzzz"}, {category : "root", type: "qqqqq", value1: "aaaaa", value2: "xxxxx"}, {category : " ...

A JavaScript async function that can be activated either by clicking the search button or by hitting the "enter" key in the input field

Recently, I've been working on an async function in Vanilla Javascript that is triggered by a click event on the search button. However, I would like to modify it so that the function can also be initiated when the "enter" key on the keyboard is press ...

npm was unable to locate the module named '../lib/npm.js'

Struggling with setting up nodejs and npm on a CentOS 7 machine without internet access. I tried copying the node-v6.2.1-linux-x64 folder with some lib modules to the machine, but it's throwing an error saying Error: Cannot find module '../lib/np ...

MUI: Autocomplete cannot accept the provided value as it is invalid. There are no matching options for the input `""`

https://i.stack.imgur.com/KoQxk.png Whenever I input a value in the autocomplete component, an unresolved warning pops up... Here's how my input setup looks: <Autocomplete id="cboAdresse" sx={{ width: 100 + " ...

Utilize AJAX to insert information into a MySQL database when a checkbox is selected

Before I got stuck here, I took a look at how a similar question was implemented here I attempted to implement the code in order to insert data into a MySQL database when a checkbox is clicked. While it may have been easier to do this on form submission, ...

Is there a way to manipulate arrays into slices within a match clause?

I have a situation where I have an enum with variants that contain arrays of different lengths. When attempting to use a `match` statement on this enum: enum EnumArray { One([i32; 1]), Two([i32; 2]), } fn main() { let arr = EnumArray::One([1] ...

How do I find the child elements within a parent node?

I am currently utilizing a jquery plugin that has rendered the following HTML layout in the browser: <html> <body> <div class="mce-container-body"> ... <input type="text" id="textedit01"> ... </di ...

Rendering an element in React Router Dom based on specific conditions

Starting a new project with the latest version of react-router-dom and following their recommendation to use createBrowserRouter. The goal is to display a different header based on the path parameters. Currently, I have set up an optional path parameter: ...

JavaScript: Efficiently Replacing Multiple Text Instances

To ensure that users do not input multiple empty paragraphs in the text editor, I have found a method to eliminate a single <p><br></p> from the text within the editor message. var str = content.replace('<p><br></p> ...

Tips on modifying the message "Please fill out this field" in the JQuery validation plugin

Is there a way to customize the message "This field is required" in the Jquery form validation plugin to display as "このフィールドは必須です"? Changing the color of the message can be achieved using the code snippet below: <style type="tex ...

Tips for modifying JSON property names during the parsing process

As outlined in the JSON.parse documentation, a reviver function can be utilized to modify the value of each property within the JSON data. Here is an example: JSON.parse('{"FirstNum": 1, "SecondNum": 2, "ThirdNum": 3}', function(k, v) { return ...

There seems to be a glitch in my programming that is preventing it

Can someone please help me troubleshoot this code? I'm unable to figure out what's going wrong. The concept is to take user input, assign it to a variable, and then display a string. However, nothing appears on the screen after entering a name. ...