Cloud Code Dependent Async Operations

54 views Asked by At

I'm not well-versed in JS but have to write some Cloud Code.

I have a few httpRequest operations returning JSON that then create Parse objects. After all those operations complete I want to run a saveAll.

Here's a shortened version of the function for readability. There are *** pointing to the async operations that need to be dependent on each other:

Parse.Cloud.job("importPlaylists", function(request, status) {


// Array to store new objects
var playlistsToSave = [];

// Iterate the countries (Sheets)
for (var j = 0; j < urls.length; j++) {

    // *** -- 1. HERE IS WHERE I LOOP THROUGH HTTPREQUESTS, GET JSON, AND CREATE A NUMBER OF PARSE OBJECTS
    // Cloud function - http request
    Parse.Cloud.httpRequest({
      url: url
    }).then(function(httpResponse) {

      // Parse response
      var json = JSON.parse(httpResponse.buffer);


      // Create playlist objects
      for (var i = 0; i < json.feed.entry.length; i++) {


        // Create Playlist objcts from json
        var Playlist = Parse.Object.extend("Playlist");
        var playlist = new Playlist();
        // ...

        // Add to caching array
        playlistsToSave.push(playlist);
      }

    },function(httpResponse) {
      // error
      console.error('Request failed with response code ' + httpResponse.status);

      status.error("Scheduled messages error: " + error);
    });
}

// *** -- 2. THIS IS THE SAVEALL OPERATION THAT NEEDS TO BE DEPENDENT ON ALL OF THOSE HTTPRESPONSES COMPLETING
// Parse - Save objects
Parse.Object.saveAll(playlistsToSave, {
    success: function(saveList) {
        status.success("Objects created successfully.");
    },
    error: function(error) {
        status.error("Unable to save objects.");
    }
  });

});

And here's the full code:

Parse.Cloud.job("importPlaylists", function(request, status) {

// ID of the Google Spreadsheet
var spreadsheetID = "someId";

// List of country codes and their Google Sheets Ids
var territories = {
    "us" : "od6",
    "gb" : "olbnsti",
    "it" : "oa6haa5",
    "es" : "oxibv7k",
    "fr" : "obisdv5",
    "nl" : "ohrgz0b",
    "de" : "ocqrxlj",
    "pl" : "oi0umg5"
}

// Array to store new objects
var playlistsToSave = [];

// Iterate the countries (Sheets)
for (var j = 0; j < territories.length; j++) {

    var countryCode = territories[j];
    var sheetID = territories[countryCode];
    var url = "https://spreadsheets.google.com/feeds/list/" + spreadsheetID + "/" + sheetID + "/public/values?alt=json"; // Make sure it is public or set to Anyone with link can view 


    // *** - 1. This loops through each Google Sheet and creates Parse objects from the JSON
    // Cloud function - http request
    Parse.Cloud.httpRequest({
      url: url
    }).then(function(httpResponse) {

      // Parse response
      var json = JSON.parse(httpResponse.buffer);


      // Create playlist objects
      for (var i = 0; i < json.feed.entry.length; i++) {

        var each = json.feed.entry[i];

        // TODO: This needs error handling - if "gsx$" doesn't exist will crash
        var name = each["gsx$name"]["$t"];
        var playlistid = each["gsx$playlistid"]["$t"];
        var description = each["gsx$description"]["$t"];
        var imageurl = each["gsx$imageurl"]["$t"];
        var categories = each["gsx$categories"]["$t"].split(','); // json returns a string from Sheet - split on commas



        // Create Parse objects 
        var Playlist = Parse.Object.extend("Playlist");
        var playlist = new Playlist();
        playlist.set("name", name);
        playlist.set("playlistId", playlistid);
        playlist.set("description", description);
        playlist.set("imageUrl", imageurl);
        playlist.set("categories", categories);
        playlist.add("territories", countryCode);


        // Add to caching array
        playlistsToSave.push(playlist);     
      }

    },function(httpResponse) {
      // error
      console.error('Request failed with response code ' + httpResponse.status);

      status.error("Scheduled messages error: " + error);
    });
}

// *** - 2. This is the saveAll operation that needs to be dependent on all the httpRequests completing
// Parse - Save objects
Parse.Object.saveAll(playlistsToSave, {
    success: function(saveList) {
        status.success("Objects created successfully.");
    },
    error: function(error) {
        status.error("Unable to save objects.");
    }
  });

});
1

There are 1 answers

2
Vintesh On

Use this async.js's each. It will allow you to make sure all httpRequests are completed.