-2
\$\begingroup\$

I am using Node.js. I have two different classes. The first one is called Controller, the second is called ServerCommunicator. Controller calls a method in SC (sendDataToDolibarrAsync), which takes a JSON array as indata and loops through it, and POSTs it to Dolibarr (Dolibarr is an ERP CRM. In my case it is mostly used as a local database.)

Controller:

this.serverCommunicator = new ServerCommunicator();
//some stuff

let result = await this.serverCommunicator.sendDataToDolibarrAsync(validatedLeads);
console.log(result);

ServerCommunicator:

async sendDataToDolibarrAsync(data){
    let result = "No Leads were added to Dolibarr, no errors were encountered";
    let writtenLeads = [];

    for(let i = 0; i < data.length; i++){
        let tempLead = data[i];
        writtenLeads.push(tempLead.name);

        let dataToBeWritten = '{' +
            '"name_alias": "' + tempLead.name + '",' +
            '"address": "' + tempLead.address + '",' +
            '"zip": "' + tempLead.zip + '",' +
            '"town": "' + tempLead.city + '",' +
            '"phone": "' + tempLead.phone + '",' +
            '"email": "' + tempLead.email + '",' +
            '"name": "' + tempLead.name + '",' +
            '"lastname": "' + tempLead.contact + '",' +
            '"firstname": ""' +
        '}';

        let options = {
            method: 'POST',
            url: 'http://localhost/dolibarr/api/index.php/thirdparties/',
            headers: { 
                'Content-Type': 'application/json',
                DOLAPIKEY: 'MY_API_KE'
            },
            body: dataToBeWritten
        };

        await request(options, function (error, response, body) {
            result = "Successfully added leads (";

            for(let i = 0; i < writtenLeads.length; i++){
                if(i === writtenLeads.length -1){
                    result += writtenLeads[i];
                }
                else{
                    result += writtenLeads[i] + ", ";
                }
            }

            result += ") to Dolibarr";
        })
        .catch( error => {
            result = "ERROR: Failed to add leads to Dolibarr \n" + error;
        });
    }

    return result;
}

This code works as expected. It loops through each object in the JSON array and PUSHes it to the Dolibarr database. The problem is that it does so synchronously, meaning it PUSHes the first object, waits for it to finish, then PUSHes the second object, wait, etc. -This makes it take a long time. (Some 12-15 seconds for only 10 objects.)

The reason I made the method async is that I want it to wait for the result variable to be populated correctly, before printing it in the console, in the Controller class.

I tried to send the entire array in one big PUSH, but the Dolibarr API doesn't like to PUSH more than one object at a time. Either that or I couldn't work out how to do it.

Is there a way to make this async, yet make all PUSHes parallell? I think yield is a keyword that might help me, but I'm not sure how to use it.

EDIT: I forgot to mention, ServerCommunicator requires request. const request = require('request-promise');

\$\endgroup\$

closed as off-topic by 200_success, Stephen Rauch, πάντα ῥεῖ, Sᴀᴍ Onᴇᴌᴀ, Toby Speight May 14 '18 at 8:04

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "Code not implemented or not working as intended: Code Review is a community where programmers peer-review your working code to address issues such as security, maintainability, performance, and scalability. We require that the code be working correctly, to the best of the author's knowledge, before proceeding with a review." – 200_success, Stephen Rauch, πάντα ῥεῖ, Sᴀᴍ Onᴇᴌᴀ, Toby Speight
If this question can be reworded to fit the rules in the help center, please edit the question.

0
\$\begingroup\$

I found the answer to my problem. Here is the code:

Controller:

this.serverCommunicator = new ServerCommunicator();
//some stuff

let result = await this.serverCommunicator.prepareToSendToDolibarr(validatedLeads);
console.log(result);

ServerCommunicator:

async sendDataToDolibarrAsync(leadToBeAdded){
    let result = "";

    let dataToBeWritten = '{' +
        '"name_alias": "' + leadToBeAdded.name + '",' +
        '"address": "' + leadToBeAdded.address + '",' +
        '"zip": "' + leadToBeAdded.zip + '",' +
        '"town": "' + leadToBeAdded.city + '",' +
        '"phone": "' + leadToBeAdded.phone + '",' +
        '"email": "' + leadToBeAdded.email + '",' +
        '"name": "' + leadToBeAdded.name + '",' +
        '"lastname": "' + leadToBeAdded.contact + '",' +
        '"firstname": ""' +
    '}';

    let options = {
        method: 'POST',
        url: 'http://localhost/dolibarr/api/index.php/thirdparties/',
        headers: { 
            'Content-Type': 'application/json',
            DOLAPIKEY: 'MY_API_KEY'
        },
        body: dataToBeWritten
    };

    await request(options, function (error, response, body) {
        result = leadToBeAdded.name;
    })
    .catch( error => {
        result = "ERROR: Failed to add leads to Dolibarr \n" + error;
    });

    return result;
}

async prepareToSendToDolibarr(data){
    let pushToDolibarrPromises = [];
    let self = this;
    let result = "";

    for(let i = 0; i < data.length; i++){
        pushToDolibarrPromises.push(self.sendDataToDolibarrAsync(data[i]));
    }

    let results = await Promise.all(pushToDolibarrPromises);

    if(results.length > 0){
        results.sort();
        result = "The following leads were successfully added to Dolibarr: \n\n";
        for(let i = 0; i < results.length; i++){

            result += results[i] + "\n ";
        }
    }
    else{
        result = "No new leads were added to Dolibarr, no errors were encountered."
    }

    return result;
}

The solution was to break apart the method into two methods (prepareToSendToDolibarr and sendDataToDolibarrAsync). The first method adds each PUSH to a promise array, and then calls Promise.all() on the array and awaits the results.

\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.