Attempting to start and restart an asynchronous function using setIntervalAsync results in a TypeError because undefined or null cannot be converted to an

Recently, I've been working on creating a web scraper that utilizes data extracted from MongoDB to generate an array of URLs for periodic scraping using puppeteer. My goal is to make the scraper function run periodically with the help of setIntervalAsync.

The issue I'm facing right now is that my current code throws an error stating "UnhandledPromiseRejectionWarning: TypeError: Cannot convert undefined or null to object at Function.values..."

puppeteer.js

 async function scrape(array){      
            // Code block to initiate loop
            let port = '9052'
            if(localStorage.getItem('scrapeRunning')=='restart'){
                clearIntervalAsync(scrape)
                localStorage.setItem('scrapeRunning') == 'go'
            }else if(localStorage.getItem('scrapeRunning') != 'restart'){
            /// Actual URL scraping using Puppeteer here ///
}

server.js

app.post('/submit-form', [
        // Form Validation Here //
    ], (req,res)=>{

        async function submitForm(amazonUrl,desiredPrice,email){
            // Establish connection to MongoDB and update existing entry/new entry
            // based on post request data
            createMongo.newConnectToMongo(amazonUrl,desiredPrice,email)
            .then(()=>{
                // Set local variable to alert scraper to use clearIntervalAsync///
                localStorage.setItem('scrapeRunning','restart');
                // Fetch updated MongoDB data before continuing...
                return createMongo.pullMongoArray();

            })
            .then((result)=>{
                // Restart scraping with new data
                puppeteer.scrape(result)
            })
        submitForm(req.body.amazonUrl, req.body.desiredPrice,req.body.email);
     }
}

createMongo.pullMongoArray()
.then((result)=>{
    setIntervalAsync(puppeteer.scrape, 10000, result);
})

The current behavior of the scraper is such that it starts running as expected after launching the server and maintains a 10-second interval between successive scrapes. However, upon submitting a form, updating the MongoDB collection with the new data, and initializing the localStorage item, the scraper encounters the aforementioned TypeError. Despite various attempts to rectify this issue, including adjusting the placement of setIntervalAsync and clearIntervalAsync within the post request code block, I have yet to find a solution. As someone relatively new to coding, especially asynchronous programming, any insights into what might be causing this problem would be greatly appreciated!

I suspect that the async nature of the code may be contributing to the problem, as all my efforts seem to indicate that the pullMongoArray function executes before newConnectToMongo finishes its task.

Answer №1

After dedicated hours to finding a solution, I believe I have finally discovered a feasible approach. To improve efficiency, I have eliminated the reliance on localStorage and removed conditional statements from the scrape function. Additionally, I have implemented a global timer variable and incorporated control functions within this file.

puppeteer.js

let timer;

function initiate(result){
    timer = setIntervalAsync(scrape,4000, result)
}

function halt(){
    clearIntervalAsync(timer)
}


async function scrape(array){       
        // code for initializing loop
        let port = '9052'
        // Puppeteer extracts urls from array here //
}

I have made adjustments to my server code so that upon server initialization, it retrieves results from MongoDB and utilizes them in the scraper start function. Furthermore, a post request triggers the stop function before updating MongoDB, fetching a fresh result from MongoDB, and then triggering the start of the scraper function again.

server.js

createMongo.pullMongoArray()
.then((result)=>{
    puppeteer.initiate(result);
})

app.post('/submit-form', [
        // Implement Form Validation Here //
    ], (req,res)=>{

        async function processForm(amazonUrl,desiredPrice,email){
            // Cease current scrape function instance
            puppeteer.halt();
            // Update or create entry in MongoDB with post request data
            createMongo.newConnectToMongo(amazonUrl,desiredPrice,email)
            .then(()=>{
                // Retrieve updated mongoDB data ...
                console.log('Fetching New Array');
                return createMongo.pullMongoArray();
            })
            .then((result)=>{
                // Restart the repeating scrape function
                puppeteer.initiate(result);
            })
      }
})

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

A HTML input field that allows for multiple values to be populated by autofill functionality, similar to the features found

Can anyone assist me with creating a text box similar to the one in Facebook's new message feature? In that feature, we are able to add multiple people in the 'To' field, all of whom are suggested from our friend list. I would like to implem ...

Using JavaScript, enter the value into the input field and then redirect the

I'm encountering a minor issue with my contact form and jQuery redirection based on input fields. Everything was working smoothly until I attempted to integrate the redirection into the form validation code. Redirection snippet: $("#signup").submit ...

Adding input values to a jQuery Ajax POST request

I am currently attempting to send form values to a remote API using AJAX. The necessary information I require from the HTML form element includes the author, string, false, and true. At the moment, I have hard-coded some values but... function sendData ...

Unlock the power of Odoo by learning how to seamlessly add custom field attributes without the need for modification

Currently, I am facing an issue with using my custom attribute for fields known as sf_group. The problem is that this attribute is not included in the field description retrieved via fields_get(). Is there a way to incorporate this custom attribute into th ...

Problems with accessing Ajax login

I'm encountering issues with an Ajax login function. Despite finding a similar question that didn't help, I'm still unsure of the problem. It's perplexing because this code functions without any problems in another project. Hopefully, ...

A guide on incorporating an event to multiple elements in vue.js

I am trying to implement a double-click event on multiple elements in Vue3. My goal is to create a table of contents data and add a double-click event to the checkboxes and favorite icons without using @dblclick="". I find it more convenient to assign a c ...

Troubleshooting the error "The 'listener' argument must be a function" in Node.js HTTP applications

I'm facing an issue resolving this error in my code. It works perfectly fine on my local environment, but once it reaches the 'http.get' call, it keeps throwing the error: "listener argument must be a function." Both Nodejs versions are iden ...

The sorting icon in jQuery Data Table's search option is not functioning

I am having an issue with jQuery DataTables. When using jQuery DataTables, it provides a default search option. However, the problem arises when I search for a particular record and if the content does not match or if I find a single record, then I need to ...

Checking for grammar and spelling errors using Node.js

How can I incorporate spell checking, grammar and punctuation error detection, greeting usage, short keyword analysis, and time tracking for each chat session in my socket.io express mongoose chat application? Although I have successfully implemented a sp ...

What is causing onbeforeunload to consistently display a dialog box?

I'm facing an issue where my javascript code displays a confirmation dialog even when there is no unsaved data. I have simplified the problem to this bare minimum: window.addEventListener("beforeunload", (e) => { e.returnValue = null; retu ...

Tips for Keeping a Responsive Image at the Forefront of a Text-Image Layout as You Scroll

I'm currently in the process of creating a website where text appears on the left side with an accompanying image on the right. The challenge I'm encountering is ensuring that as users scroll, the image adjusts dynamically based on the associated ...

Parsing temporary storage of database query results

My experience with OOP languages like C# and Java has been good, but I am relatively new to JavaScript/TypeScript. I find callback functions confusing, especially when using them with the BaaS ParseDB. For example, finding all playlists for a certain user ...

Sort an array by mapping it in decreasing order based on the total sum of its elements

I came across a JSON structure that looks like the following: { "user": [ {"username": "x1", "pfp": "", "scores": [{"easy": 10, "normal": 1, "hard": 2, "oni&q ...

How can it be that "Function" actually functions as a function?

In JavaScript, there exists a function called "Function". When you create an instance of this function, it returns another function: var myfunc = new Function('arg1','arg2','return arg1+arg2'); In the above example, the vari ...

Node.js failing to return external API call to its original requester

In our app structure, we use AngularJS on the client side, Node.js on the server side, and a service layer for external API calls. The call chain seems to be successful up until the Node.js layer, but the expected value isn't reaching back to the orig ...

Slider with Dual Images: A Visual Comparison

I'm currently working on a webpage that features before and after images using a slider based on mouse movement to display both pictures. I am trying to incorporate multiple sliders on the same page but have been facing difficulties in getting them to ...

Utilizing AngularJS to make an API call with $http method and handling a

I am attempting to make a call to my webservice using "$http". When I use "$ajax", it works fine. Here is an example of jQuery $Ajax working correctly: $.ajax({ type: "Get", crossDomain: true, contentType: "application/json; chars ...

What is the proper way to detach an event listener from a class?

I am facing a challenge when trying to remove an event listener. After running the script, I receive an error message stating that changeGirl.off("click") is not a function. Despite this issue, everything else within the code is working perfectly fine. Any ...

Inconsistency in @nuxtjs/i18n locales after refreshing the page

I am currently working on an application where I am implementing language management, but I have encountered a difficulty. I am using the latest version of @nuxtjs/i18n. Changing the language successfully updates the URL and labels, yet upon refreshing the ...

What is the best way to send various parameters to a component using [routerLink] or router.navigate?

My app-routing.module.ts is configured as shown below: const routes: Routes = [ { path: "branches/:branch", component: BranchesComponent }, // ... ]; In addition, in my app.component.html, I have the following code: <li> ...