During the program's runtime, p5.js unexpectedly encounters a problem reading my update function at a random point

I'm currently working on a project where I want to create a program that removes particles from an array when they reach the right end of the canvas.


let P = [];
let n = 10;

function setup() 
{
    createCanvas(500,500);
    for(let i = 0; i < n; i++)
        P.push(new particle());
}

function draw() 
{
    background(0);
    for(let i = 0; i < n; i++)
    {
        if(P[i].out == true)
        {
            P.splice(i, 1);
            n--;
        }
        P[i].update();     
        P[i].plot();
        console.log(P.length)
    }   
}

class particle
{
    constructor()
    {
        this.brightness = 0;
        this.vel = random(1);
        this.dia = 3;
        this.x = 0;
        this.y = random(height);
        this.out = false;
    }

    update()
    {
        this.x += this.vel;
        if(this.x >= width)
            this.out = true;
    }

    plot()
    {
        noStroke();
        fill(255);
        circle(this.x, this.y, this.dia);
    }  
}

Most of the time, everything seems to be running smoothly with my program. However, as the array size decreases after particles are removed, I encounter an error message:

Uncaught TypeError: Cannot read property 'update' of undefined

This issue is perplexing because there shouldn't be any trouble reading the 'update' function since it's been used without issues previously in the loop.

Answer №1

The problem arises when you delete elements from an array while iterating through it. When P.splice(i, 1); removes the last element in the array, P[i].update(); will try to access an index that is out of bounds, leading to the error message "Uncaught TypeError: Cannot read property 'update' of undefined"

To avoid this issue, I suggest looping through the array backwards:
(Refer also to Looping through array and removing items without breaking the for loop)

let i = P.length;
while (i--) {
    if (P[i].out == true) {
        P.splice(i, 1);
        n--;
    } else {
        P[i].update();     
        P[i].plot();
    }
}

Take a look at the example below:

let P = [];
let n = 10;

function setup() 
{
    createCanvas(500, 500);
    for(let i = 0; i < n; i++)
        P.push(new particle());
}

function draw() 
{
    background(0);

    let i = P.length;
    while (i--) {
        if (P[i].out == true) {
            P.splice(i, 1);
        } else {
            P[i].update();     
            P[i].plot();
        }
    }   
}

class particle
{
    constructor()
    {
        this.brightness = 0;
        this.vel = random(1);
        this.dia = 3;
        this.x = 0;
        this.y = random(height);
        this.out = false;
    }

    update()
    {
        this.x += this.vel;
        if(this.x >= width)
            this.out = true;
    }

    plot()
    {
        noStroke();
        fill(255);
        circle(this.x, this.y, this.dia);
    }  
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.0.0/p5.min.js"></script>

Answer №2

To effectively remove elements from the array, it is essential to iterate through it in reverse order:

function display() {
    setBackdrop(0);
    for(let x = n - 1; x >= 0; x--) {
        if(A[x].exited == true) {
            A.splice(x, 1);
            n--;
        }

        A[x].update();     
        A[x].view();
        console.log(A.length)
    }   
}

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

Achieving synchronization within the 'it' block using Protractor

I am currently experiencing synchronization issues in the 'it' block of my code. The following snippet illustrates the problem: it('Some Download Operation',function() { console.log("before"); myobj.clickOnDownloadBtn(); ...

The post method in Express.js is having difficulty parsing encoded data accurately

I'm currently working on an AngularJS code that sends a POST request like this: var req = { method: 'POST', url: 'http://localhost:3300/addInventoryItem', headers: { 'Content-Type': 'application/x-www-form- ...

A guide to serving multiple HTML files with Node.js

After creating a mongoDB form using nodeJS, I successfully served the signUp page. However, clicking on any other links to navigate to different pages resulted in an error message saying "Cannot GET /index.html". I am struggling with how to properly serv ...

JavaScript checkboxes not being recognized by Node element

Located on the left side of the page, there is a feature that allows me to include selected options in a list with the same name attribute. These selections will then be sent as part of the entire form to the Node backend. Most of the elements on the page ...

Validate input JQuery only when specific radio buttons are chosen

My form currently has basic validation set up like this: <script type="text/javascript"> $(function() { $("#postform").validate({ rules: { ...

Validation of time picker consistently returns false

While using the daterangepicker library for my form validation with JavaScript, I encountered an issue with the time field. It returns false and displays an error message saying: "Please enter a valid time, between 00:00 and 23:59," preventing me from addi ...

Encoding a multidimensional associative array into JSON using PHP

Having used php's json_encode() function frequently in the past, I am puzzled by the current issue... Note: Error checking has been omitted for clarity. //PHP <?php session_start(); require 'global/query.php'; $sql = "SELECT sfl,statio ...

Start Vue.js development server with SSL enabled (for secure HTTPS serving)

Issue with Development Environment: Recently, I encountered an obstacle related to enforcing HTTPS on external hosts as explained in "Deprecating Powerful Features on Insecure Origins". This problem arose because I have my development setup on my laptop an ...

Issues with displaying AJAX Bootstrap Modals

I'm struggling to display a Bootstrap modal with dynamically generated content from the database. The data is not showing up in the modal body, and I've been troubleshooting this issue for quite some time now. Modal <div class="modal fade" i ...

Is there a way to efficiently navigate a local JSON file using React JS?

What is the best way to extract data from a JSON file and utilize it within my code? I attempted importing the file and logging it in the console, but all I get is Object {}: import jsonData from "./file.json"; console.log(jsonData); This is the content ...

Tips for creating multiple popups using a single line of JavaScript code

I am new to JavaScript and I am attempting to create a popup. However, I am facing an issue in opening two divs with a single line of JavaScript code. Only one div opens while the other remains closed despite trying various solutions found on this website. ...

Utilizing jQuery, the code can modify a basic element on a webpage by extracting JSON data from two external device buttons

This project I'm working on for school is quite simple. I am trying to change the background color of a webpage and more with the use of an external device that has two buttons (microbit a and b) connected to a serial port. The device writes data stri ...

Cycle through an array an unlimited number of times using a combination of forEach and setTimeout

In my myClass, I am facing an issue with the method. When it reaches the end of the array, instead of starting over from 0, it simply stops. this.jsonParse = function() { for (var i = 0; i < this.numberOfPhotos; i++){ (function(index, sele ...

Issue encountered when attempting to utilize multiple datasets with Twitter Typeahead/Bloodhound

Hello, I am currently learning how to use Typeahead and Bloodhound with the latest javascript. Below is a snippet of my code: Html: <div id="multiple-datasets"> <input class="typeahead" type="text" placeholder="NBA and NHL teams"> </div ...

How can you apply a class to a different element by hovering over one element?

Is there a way to darken the rest of the page when a user hovers over the menu bar on my website? I've been playing around with jQuery but can't seem to get it right. Any suggestions? I'm looking to add a class '.darken' to #conte ...

Add the value to the array in MongoDb only if it does not already exist in

Looking to make updates to a nested array within a document only if the item is not already included in the array: await userCollection.findOneAndUpdate( { _id: ObjectId('616acc597ebda90ca6ffee21') }, { 'devices': { ...

How come running `npm install <folder>` results in installing different dependencies compared to `npm install lib`?

My current project, project1, relies on <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="5221262b3e37367f313d3f223d3c373c262112667c6">[email protected]</a>. When attempting to integrate project2 into project1 as a ...

Issue with Chrome extension's popup not displaying

I was developing a chrome extension, but I encountered an issue where the popup does not display when clicking on the icon. After researching online, I found suggestions to change page_action to browser_action. However, even after making this adjustment, ...

Multipart form data processing without specifying files

I need help with uploading an image using node.js, express, and multiparty. My code is as follows: HTML <!DOCTYPE html> <html> <body> <form method="post" action="/img"> Select image to upload: <input type="file" name= ...

Creating a function in a JavaScript module that can be exported to the window namespace

One of the goals of modules is to protect variables and functions defined inside from being accessed outside the script. However, if you want to export a specific function for global use, there are ways to accomplish this. Merely assigning it to the window ...