0

I am trying to read a file on parse.com and using a for loop iterate over all the records present in it. On each record, I need to perform 4 operations, each dependent on the other. Can someone please guide how I can do that so that each record is processed in the for loop.

Parse.Cloud.httpRequest({
            url: urlValue
        }).then(function(fileResponse) {
            console.log("processUploadFile:httpRequest:response:" + JSON.stringify(fileResponse.buffer.length));
            // console.log("processUploadFile:Text:" + fileResponse.text);

            var records = fileResponse.text.split("\r");

            for (var i = 0; i < records.length; ++i) {
                // console.log("Record:" + i + " detail:" + records[i] + "\n\n");
                var record = records[i];


                        console.log("processUploadFile:adding patient");
                        Parse.Cloud.run("addPatient", {
                            record:record
                        }, {
                            success: function(objectId) {
                                console.log("Created objectId:" + JSON.stringify(objectId));
                                Parse.Cloud.run("addProvider", {
                                    record:record
                                }, {
                                    success: function(objectId) {
                                        console.log("Created objectId:" + JSON.stringify(objectId));

                                        Parse.Cloud.run("addLocation", {
                                            record:record
                                        }, {
                                            success: function(objectId) {
                                                console.log("objectId:" + JSON.stringify(objectId));
                                            },
                                            error: function(error) {
                                                console.log(JSON.stringify(error));
                                            }
                                        });
                                    },
                                    error: function(error) {
                                        console.log(JSON.stringify(error));
                                    }
                                });
                            },
                            error: function(error) {
                                console.log(JSON.stringify(error));
                            }
                        });
                    };
                }
            }


            response.success();
        });
7
  • This sort of nested-event madness is why I created www.taskrunnerjs.com - although there are lots of other alternatives. IMO those styles of chaining are much easier to read and comprehend than this. (This is just an opinion, not so much an answer. Honestly it's not entirely clear what you're asking.) Commented Mar 4, 2015 at 17:49
  • 1
    Do those subsequent steps depend on each other, in other words, e.g. must addPatient be completed before before addProvider can work, or may these be performed in any order? Commented Mar 4, 2015 at 18:03
  • @danh... yes ... addPatient is dependent on completion of addProvider Commented Mar 4, 2015 at 18:24
  • @brianvaughn ... www.taskrunnerjs.com looks great... but I don't think I can use that on parse.com. Can I use promises? Commented Mar 4, 2015 at 18:26
  • 1
    you can (and should) use promises with parse.com on both client and server. @brianvaughn's library looks to be well thought out, though I've never used it. Commented Mar 4, 2015 at 18:30

1 Answer 1

1

The right right answer depends on the semantics of those operations, whether they depend on each other in any way. The other part of a right right answer accounts for transaction rate limits and timeouts imposed by parse.com. That also depends on what happens in the cloud operations and how much data is being processed.

But the right answer (as opposed to right right) is to perform operations serially by chaining promises' then(), and to perform groups of operations concurrently (or in arbitrary order) with Parse.Promise.when().

One such ordering would look like this:

var patientQs = [];
var providerQs = [];
var locationQs = [];
var records;

Parse.Cloud.httpRequest({url: urlValue}).then(function(fileResponse) {
    console.log("processUploadFile:httpRequest:response:" + JSON.stringify(fileResponse.buffer.length));
    records = fileResponse.text.split("\r");
    for (var i = 0; i < records.length; ++i) {
        // console.log("Record:" + i + " detail:" + records[i] + "\n\n");
        var record = records[i];
        patientQs.push(Parse.Cloud.run("addPatient", {record:record}));
        providerQs.push(Parse.Cloud.run("addProvider", {record:record}));
        locationQs.push(Parse.Cloud.run("addLocation", {record:record}));
    }
    return Parse.Promise.when(patientQs);
}).then(function() {
    // since the result of addPatient is an objectId, arguments
    // will be the corresponding objectIds for each run 
    for (var i=0; i<arguments.length; i++) {
        console.log(arguments[i] + " is the object id for input record " + JSON.stringify(records[i]));
    }
    return Parse.Promise.when(providerQs);
}).then(function() {
    return Parse.Promise.when(locationQs);
}).then(function() {
    response.success();
}, function(error) {
    response.error(error);
});

This says, "go thru the http-retrieved records, and first add all of the patients for those records, then add all of the providers, and so on".

Or, you could group the operations by input record, like this:

Parse.Cloud.httpRequest({url: urlValue}).then(function(fileResponse) {
    console.log("processUploadFile:httpRequest:response:" + JSON.stringify(fileResponse.buffer.length));
    var records = fileResponse.text.split("\r");
    var recordQs = [];

    for (var i = 0; i < records.length; ++i) {
        // console.log("Record:" + i + " detail:" + records[i] + "\n\n");
        var record = records[i];
        recordQs.push(processARecord(record));
    }
    return Parse.Promise.when(recordQs);
}).then(function() {
    response.success(arguments);
}, function(error) {
    response.error(error);
});

function processARecord(record) {
    var result = {};
    return Parse.Cloud.run("addPatient", {record:record}).then(function(objectId) {
        console.log(objectId + " is the object id for input record " + JSON.stringify(record));
        result.patientId = objectId;
        return Parse.Cloud.run("addProvider", {record:record});
    }).then(function (providerId) {
        result.providerId = providerId;
        return Parse.Cloud.run("addLocation", {record:record});
    }).then(function(locationId) {
        result.locationId = locationId;
        return result;
    });
}
Sign up to request clarification or add additional context in comments.

9 Comments

this is something close to what I was looking for. I didnt know, we could add those many "then" blocks... How do we a return a value from the block though. after the addPatient completes, I need the objectId of the currently added patient.
also, can't we perform addpatient, then addProvider then addLocation for the same record then move on to the next record?
@i_raqz - re the first comment: see edit. var args to the then() will contain objects corresponding to each fulfilled promise. re your second comment: yes, this is easily done by making a chain of promises for each record, rather than a group for each function type.
@i_raqz - regrouped to illustrate point about grouping by input rather than by function. The bigger point is that chaining then()'s gives you sequence and performing when()'s gives you semi-concurrence.
this is exactly what i was looking for..you gave a me a little tutorial about using Promise as well async calls.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.