The map function comes to an end once it has successfully executed once

I am currently working on a project where I need to fetch data from MySQL, map through the array returned, and send out tweets based on certain criteria. However, my current code only sends a tweet for one element in the array when it should actually be sending multiple tweets as it iterates through all elements. Below is the snippet of my code:

array.items.map(item => {
  con.query(`SELECT username FROM users where country="${item.country}"`, async function (err, result, fields) {
    if (err) throw err;
    console.log(result);

    result.length > 0 && result.map(async user => {
      try {
        await sendTweet(`Hello ${user.username}, your selected country is ${item.country}`);
      } catch (error) {
        console.error(error.body)
        return false
      }
    })
  });
});

I seem to be having trouble with this logic. Any guidance or help would be greatly appreciated. Thank you.

Answer №1

There is no necessity for async and await in this scenario.

let numbers = [4, 5, 6];
numbers.forEach(num => {

  // databaseRequest
  setTimeout(function(error, data) {
    if (error) throw error;

    data = [44, 55, 66];

    data.length > 0 && data.forEach(customer => {
      try {

        // sendEmail
        setTimeout(() => {
          console.log(`Greetings ${customer.name}, your item cost is ${num.price}`);
        }, 600);

      } catch (exception) {
        console.error(exception);
        return false;
      }
    })
  }, 600);
});

Answer №2

One possible solution is to leverage the Promise.all method.

if (result.length) {
  try {
      await Promise.all(result.map(user => {
          return sendTweet(`Greetings ${user.username}! Your chosen country is ${item.country}`);
      }));
  } catch(e) {
      //Error handling logic goes here
  }
}

Answer №3

Here's one way I might phrase it:

In my opinion, waiting for the sendTweet function is unnecessary.

If you anticipate that a field may be undefined, you can set a default value using optional chaining methods. Please refer to optional chaining documentation for more information, specifically regarding the 'username' example provided below.

async function tweetAll(item, error, users) {
  if(error) {
    console.log('error', error.message)
  }
  else {
    for(const user of users) {
      sendTweet(`Hello ${user?.username ?? 'User'}, your selected country is ${item.country}`)
    }
  }
}

for(const item of array.items){
  con.query(`SELECT username FROM users where country="${item.country}"`, (error, users) => tweetAll(item, error, users))
}

Answer №4

I don't have much experience with using MySQL in node.js, but based on your code, here's what I understand.

array.items.map(user => {
  do something async; 
});

The issue here is that the async process will only run once because the loop doesn't wait for it to complete.

Instead, you can try this approach:

array.items.forEach(async user => {
await 'do something async'
});

This way, you ensure that the async process completes before moving on. I'm not sure if MySQL supports await, but you can use Promises for handling asynchronous operations.

EDIT: If you simply want to fetch data for multiple WHERE conditions, consider optimizing your query like this:

Instead of looping through where queries, consolidate them into a single WHERE IN query.

str = '(';
arr.map(item => {
  str += item.toString();
}

str += ')';

conn.query(`SELECT * from table WHERE country IN ${str}`)

Let me know how it goes. Here's more information on SQL IN queries

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

Utilizing AngularJS to dynamically apply CSS classes based on the $index value

Is there a way to style my div based on the ng-repeat index, applying different styles for odd and even rows? The row with an even index should have all classes specified for the odd one plus additional classes. Controller: var odd = { 'class1&apos ...

What occurs to the JavaScript code following the compilation of the app using Titanium Mobile?

After installing Titanium from appcelerator, I successfully built the "KitchenSink" example application. Now, I'm curious about where the javascript code ends up in a built app. I searched through the Xcode project and the resulting application loca ...

Using PHP to Showcase Weather Information from JSON API

Despite going through numerous questions, I'm still struggling with this. I have never worked with JSON data before, and what should be simple is proving to be quite tricky. Here is a sample JSON response from the DarkSky Weather API: { "latitud ...

What is the process for refreshing HTML elements that have been generated using information from a CSV document?

My elements are dynamically generated from a live CSV file that updates every 1 minute. I'm aiming to manage these elements in the following way: Remove items no longer present in the CSV file Add new items that have appeared in the CSV file Maintai ...

Issue with npm installation leading to missing node_modules directory

When attempting to run npm install . in a local directory, I keep encountering the following errors: npm ERR! install Couldn't read dependencies npm ERR! Darwin 15.2.0 npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "install" "." npm ERR! no ...

Is there a way to make images appear on the screen only when they come into view on

While exploring the internet, I came across something quite intriguing on a website: As you scroll down the page, images only load when they come into view in the browser window. This is a feature I have never seen before and I am curious if anyone else h ...

Obtaining HTML data with ajax within a WordPress post

Greetings! I've been putting together a website and I'm eager to include a unique timeline in each of my posts. I'm utilizing WordPress for this project. However, since the timeline I want to insert will vary from post to post, I am unable t ...

Error: Unable to execute testFunction as it is not defined as a function

I have a unique Vue application with an upload component that allows users to select an image (via dropzone), crop it using cropperjs, and then return the cropped image back to the dropzone. Now, I am looking to compress the image right before uploading it ...

Combining associative arrays in PHP

I need to merge an associative array in a specific way using PHP. The data is not already merged, so I have to figure out how to do it. Here is the initial array: Array ( [0] => Array ( [name] => Color [value] => ...

Instructions for relocating the ending of a javascript range to a sentence within the Chrome browser

When working with a javascript range object, Internet Explorer offers a moveEnd method that can shift the end of a range by a specified number of sentence units. How can a similar functionality be achieved in Chrome? Below is the code I have written that ...

Design a dropdown menu with options that correspond to the specific data attribute, showing both values and text

I have a snippet below where I am trying to create a select dropdown option based on the data attributes (data-select-text and data-select-values) of the button that is currently clicked. The snippet works for the most part, except I am struggling with ext ...

Displaying values in form fields when a specific class is present

Whenever I input and submit the form fields correctly using #submit_btn, my values disappear. However, when they are not valid, this issue does not occur. I attempted to address this problem with jQuery: $('#submit_btn').click(function() { i ...

Is there a way for me to divide the data in a JSON file and display user tags in place of their IDs?

Looking to create a list admins command for a bot, I'm facing challenges in converting user ids to tags within the command. Take a look at what I have accomplished so far: const { MessageEmbed } = require('discord.js'); const { readFileSync, ...

Modifying Props in Reactjs: Ways to update data passed from parent component to child component

Currently, I am working on a project where I have multiple components on a page and pass data between them using props. The issue arises when I update the data in the parent component but the child component still uses the old data. Let me illustrate with ...

The value of msg.member is empty following the messageReactionAdd event

Whenever someone reacts on my server, it triggers the messageReactionAdd event. However, I am encountering difficulty in retrieving the member object of the author of a message that someone reacted to: module.exports = async (client, messageReaction, user) ...

Adding node-neat along with other files to the node-sass grunt task

I've been facing some challenges with using node-neat in conjunction with grunt-sass, specifically when trying to add additional include paths. Initially, everything works fine when I set it up like this: options: { includePaths: require(' ...

What is the best location to place Sentry's setUser function in a Next.js application?

I have been working on integrating user data into Sentry's scope globally so that user information is passed to it every time an error or event occurs. My application is developed in Next.js, and I followed the configuration mentioned in Sentry' ...

Oops! An unexpected field was encountered while trying to use the uploadMultiple function from dropzone.js

I was looking for a way to allow users to select images to accompany their reviews. That's when I came across dropzone.js. However, I encountered an issue when trying to send multiple images in one request. I expected the req.files to contain an arra ...

Unusual behavior involving the selection of $stateParams

Seeking a solution for updating angular-ui route parameters based on select field changes. Issue: The route successfully updates with the selected parameter, but the select field does not reflect the change in option selection. Check out the Plunkr. Clic ...

Unable to retrieve slots from child component's dynamic function in Vue2

When passing <slot name="success-mark"> to a child component, it is done as shown below: <vue-dropzone ref="myVueDropzone" id="dropzone" :options="dropzoneOptions"> <slot name="success-mark"><i class="fa fa-trash"></i>& ...