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

Pausing JavaScript Execution Until the Completion of an Ajax Call

As I edit values in a form fetched from the database via AJAX, clicking an element opens a modal box. The details are then fetched from the server and placed in the appropriate form elements. The data contains a pin code, and I need to retrieve all the ar ...

Why isn't my React image updating its source right away? What are some solutions to this issue?

I currently have a basic <img> tag with a specified src attribute. <img src={src} /> When I update the src attribute from, let's say /1.jpg to /2.jpg, there is a delay in loading the new image. React still displays the old image (/1.jpg) ...

Navigating a dynamic table by looping through its generated tr elements

I am currently working with a dynamically created tr table that includes individual rows of data and a fixed total sum at the bottom. The total sum does not change dynamically. var tmp = '<tr id="mytable"> <td id="warenid">'+data1.id ...

What is the best way to correctly showcase dynamic pages in ExpressJS?

Within my app.js file, there exists an array of objects that is defined as follows: var people = [ {name: "Henrique Melo", username: "heenrique", email: "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="7a121f1408130b0f1 ...

Unusual issue in IE causing rendering problems in reporting services

Currently, I am creating a report using Reporting Services 2008, MVC 2, and Ajax as my development technologies. When I generate the report, everything displays perfectly if there is data present. However, if there is no data, the report body gets cut off ...

Tips for incorporating a spinner during content loading within AngularJS

When the user clicks on the "Search" button, content will load and the button label will change to "Searching" with a spinner shown while the content is loading. Once the content has loaded (Promise resolved), the button label will revert back to "Search" ...

The duration spent on a website using AJAX technology

We conducted an online survey and need to accurately calculate the time spent by participants. After using JavaScript and PHP, we found that the calculated time is not completely accurate. The original script was sending server requests every 5 seconds to ...

What are the methods for providing both successful and unsuccessful promises, with or without data?

Seeking guidance on how to return a promise and an object named output before or after the $http call in AngularJS, specifically using Typescript. How can I ensure it works correctly? topicNewSubmit = (): ng.IPromise<any> => { var self = t ...

My Next.js application is successfully making Axios API calls to my localhost while running on the server-side

In my Next.js and React application, I am utilizing the axios library. Initially, I was able to successfully call the API from the server using getStaticProps() and render the initial data properly. However, when attempting to fetch more data from the clie ...

CSS code for vertical navigation arrows to remain on both the left and right sides of the webpage

I'm struggling a bit with the CSS. I want to recreate the same effect as seen on . The left and right navigation arrows stay fixed vertically even when scrolling up or down the page. Does anyone have any code examples for that? ...

Achieving a smooth transition from a blur-out effect to a blur-in effect on a background Div

I created a blur in/out effect for my landing page, but it's not functioning as expected and I'm not sure why. It blurs out correctly, but the issue arises when I want the underlying Div to fade in. Currently, it just appears abruptly after the ...

I recently started learning Next.js and I'm interested in organizing my website with multiple page folders but still using a single dynamic route labeled as [id]

my-nextjs-app/ |-- .next/ |-- node_modules/ |-- public/ |-- src/ | |-- components/ | |-- men/ | | |-- [id]/ | | |-- page.tsx # Specific ID static page for Men's category | | |-- page.tsx # General stat ...

Can I employ a PHP script as a "server" for a React application?

As I am using shared hosting without Node installed, I can't utilize Express as a server (or any other node-related features xD). The issue arises when fetching data from the Behance API in my app and encountering a CORS error. To address this probl ...

Executing system commands using Groovy is a breeze

One of the scripts I have is a sample.js script that allows me to view files located on the server myHost. It works perfectly: var exec = require('ssh-exec') var v_host = 'myHost' exec('ls -lh', { user: 'username&apo ...

Troubleshooting MongoDB aggregate lookup failure when using multiple parameters

In my data retrieval process from the comments table, everything is functioning properly. However, I am aiming to optimize performance by performing a join equivalent on the users collection to fetch additional user details associated with each comment. B ...

Working with jQuery, CSS, and functions to modify the current tag's class

Let's keep it brief and straightforward: Here is my HTML <div id="headerVideoControls" class="overlayElement"> <div id="videoMuteUnmute" onclick="muteUnmuteVideo('headerVideo')">mute button</div> </div> Edited ...

Creating a button that allows updates without refreshing the page can be achieved by implementing

Here are the items I have: <table> <tr> <th> id </th> <th> name </th> <th> update </th> </tr> <tr> ...

Issue: missing proper invocation of `next` after an `await` in a `catch`

I had a simple route that was functioning well until I refactored it using catch. Suddenly, it stopped working and threw an UnhandledPromiseRejectionWarning: router.get('/', async (req, res, next) => { const allEmployees = await employees.fi ...

Receiving a 401 error while attempting to make an axios get request with authentication headers

I have been utilizing axios in my React project to fetch data from MongoDB. However, I am facing a challenge with the axios get requests returning a 401 error when I include my auth middleware as a parameter. This middleware mandates that the user must pos ...

The command is failing to include functionality with the yarg npm package

I have been attempting to incorporate a command using yargs, however, after executing my code, the command does not seem to be added successfully. Below is the snippet of what I am attempting: const yargs = require('yargs') //create add command ...