1

I'm trying to iterate and print out in order an array in Javascript that contains the title of 2 events that I obtained from doing web scraping to a website but it prints out in disorder. I know Javascript is asynchronous but I'm new in this world of asynchronism. How can I implement the loop for to print the array in order and give customized info?

agent.add('...') is like console.log('...'). I'm doing a chatbot with DialogFlow and NodeJs 8 but that's not important at this moment. I used console.log() in the return just for debug.

I tried the next:

async function printEvent(event){
    agent.add(event)
}

async function runLoop(eventsTitles){
    for (let i = 0; i<eventsTitles.length; i++){
       aux = await printEvent(eventsTitles[i])
    }
}    

But i got this error error Unexpected await inside a loop no-await-in-loop

async function showEvents(agent) {
    const cheerio = require('cheerio');
    const rp = require('request-promise');
    const options = {
        uri: 'https://www.utb.edu.co/eventos',
        transform: function (body) {
            return cheerio.load(body);
        }
    }

    return rp(options)
        .then($ => {

            //** HERE START THE PROBLEM**
            var eventsTitles = [] // array of event's titles
            agent.add(`This mont we have these events available: \n`)
            $('.product-title').each(function (i, elem) {
                var event = $(this).text()
                eventsTitles.push(event)
            })
            agent.add(`${eventsTitles}`) // The array prints out in order but if i iterate it, it prints out in disorder.

            // *** IMPLEMENT LOOP FOR ***

            agent.add(`To obtain more info click on this link https://www.utb.edu.co/eventos`)
            return console.log(`Show available events`);

        }).catch(err => {
            agent.add(`${err}`)
            return console.log(err)
        })
        
}

I would like to always print out Event's title #1 and after Event's title #2. Something like this:

events titles.forEach((index,event) => {
    agent.add(`${index}. ${event}`) // remember this is like console.log(`${index}. ${event}`)
})

Thanks for any help and explanation!

German
  • 192
  • 1
  • 11
  • Possible duplicate of [Asynchronous Process inside a javascript for loop](https://stackoverflow.com/questions/11488014/asynchronous-process-inside-a-javascript-for-loop) – Jonas Høgh Oct 22 '19 at 06:43
  • `eventsTitles.forEach((event,index) => {` jquery is doing this wrong. But they do it wrong for so long, that they can not change this anymore. besides that, you can do `var eventsTitles = $('.product-title').toArray().map(item => item.textContent);` – Thomas Oct 22 '19 at 06:47
  • @JonasHøgh not sure if thats an exact dupe – Rajesh Oct 22 '19 at 06:52
  • @JonasHøgh I don't see how these two questions would be related. Because the both contain async and loops? – Thomas Oct 22 '19 at 06:57
  • @Thomas Hi, but the problem it's not the array. When i print out the array it looks in order. The problem is when i iterate it in a for loop. Even i tried to use await but it says i can't use await in loop for – German Oct 22 '19 at 06:59
  • `The problem is when i iterate it in a for loop` how do you determine that the output is not in the right order? what do you expect to see in contrast to what do you get? And please include some output. – Thomas Oct 22 '19 at 07:02

1 Answers1

1

There no async case here but if you still face difficultly than use this loop

for (let index = 0; index < eventsTitles.length; index++) { const element = eventsTitles[index]; agent.add(${index}. ${element}) }

Ankur Patel
  • 478
  • 3
  • 6
  • Yesssss I felt great and terrible right after read your answer because I realized it's true there isn't async case. I'm building a chatbot so I checked from another console the answers and the problem seems to be Telegram Bot that show the info in disorder. Google Assistant do show the info serialized. Thank you so much! I used your loop for and it works perfectly – German Oct 22 '19 at 09:13