Cannot set headers after they are sent to the client - Please help me understand this in my code

133 Views Asked by At

I've got this error in my Parse cloud code and I don't really understand how THIS SOLUTION applies to my code because I am using Parse cloud code. I do understand that the server is a via which runs Parse using javascript, which then runs CRUD actions in the database. But because it can't really be seen by the actual HTTP requests I can't tell whats happening and where I should adjust my code.

If someone could point out to me what I'm doing wrong and how I could adjust my code that would be great. Also is this even a big deal? If I leave my cloud code like below in production would this be a big deal? Everything runs perfectly as per high level results right now with this function.

I have the idea I should be continuing the .then() funtions. If this is the case, just how many long can this tree go?

Parse.Cloud.define("ccCreateGroupRole", async function(request){
    let user = request.user.id;
    let acl = new Parse.ACL();
    acl.setReadAccess(request.user, true);
    acl.setWriteAccess(request.user, true);
    let adminRole = new Parse.Role("Group_" + user, acl);
    adminRole.save(null, { useMasterKey: true }).then(function() {
        adminRole.getUsers().add(request.user);
        adminRole.save(null, { useMasterKey: true }).then(function() {
            console.log("Role created " + adminRole.id);
        });
    });

    // Create Sync Status objects
    let masterSyncStatus = {user: user, syncStatus: true};
    let newUserSyncStatus = {user: user, syncStatus: true};
    let masterArray = [];
    let newUserArray = [];
    masterArray.push(masterSyncStatus);
    newUserArray.push(newUserSyncStatus);

    // Initialize Sync Status class object by groupID
    let SyncStatus = Parse.Object.extend("SyncStatus");
      let syncStatus = new SyncStatus();
      syncStatus.set("groupName", "Group_" + user);
      syncStatus.set("masterSyncStatus", masterArray);
      syncStatus.set("newUserSyncStatus", newUserArray);
    await syncStatus.save(null, { useMasterKey: true });

    // Write own publicKey to user class
    let UserAddPublicKey = Parse.Object.extend("_User");
    let userAddPublicKey = new UserAddPublicKey();
    userAddPublicKey.set("objectId", request.user.id);
    userAddPublicKey.save(null, { useMasterKey: true });
  });

2

There are 2 best solutions below

3
jfriend00 On BEST ANSWER

Your original code was not awaiting all the promises you have. Instead, you were using a mix of await and .then(), but not controlling the flow properly everywhere.

When you nested all the .then() inside of each other, you were able to properly sequence all the asynchronous operations so that B waited until A was done and C waited until B was done. Your original code was not doing that.

But, you can do all that with await too like this by using await on all asynchronous operations to make sure you're sequencing everything:

Parse.Cloud.define("ccCreateGroupRole", async function(request) {
    let user = request.user.id;
    let acl = new Parse.ACL();
    acl.setReadAccess(request.user, true);
    acl.setWriteAccess(request.user, true);
    let adminRole = new Parse.Role("Group_" + user, acl);
    await adminRole.save(null, { useMasterKey: true });
    adminRole.getUsers().add(request.user);
    await adminRole.save(null, { useMasterKey: true });
    console.log("Role created " + adminRole.id);

    // Create Sync Status objects
    let masterSyncStatus = { user: user, syncStatus: true };
    let newUserSyncStatus = { user: user, syncStatus: true };
    let masterArray = [];
    let newUserArray = [];
    masterArray.push(masterSyncStatus);
    newUserArray.push(newUserSyncStatus);

    // Initialize Sync Status class object by groupID
    let SyncStatus = Parse.Object.extend("SyncStatus");
    let syncStatus = new SyncStatus();
    syncStatus.set("groupName", "Group_" + user);
    syncStatus.set("masterSyncStatus", masterArray);
    syncStatus.set("newUserSyncStatus", newUserArray);
    await syncStatus.save(null, { useMasterKey: true });

    // Write own publicKey to user class
    let UserAddPublicKey = Parse.Object.extend("_User");
    let userAddPublicKey = new UserAddPublicKey();
    userAddPublicKey.set("objectId", request.user.id);
    await userAddPublicKey.save(null, { useMasterKey: true });
});
0
RobbB On

I'm not sure if this is "javascript correct" but I am chaining together many .then({}) and I do not get an error anymore. I don't understand why the async/await I was using before does not work... but this solves my main question.

EDIT: The async/await did work but I get the error in Parse logs.

Can anyone explain this better? If so correct answer is still up for grabs.

Parse.Cloud.define("ccCreateGroupRole", async function(request) {
    let user = request.user.id;
    let acl = new Parse.ACL();
    acl.setReadAccess(request.user, true);
    acl.setWriteAccess(request.user, true);
    let adminRole = new Parse.Role("Group_" + user, acl);
    adminRole.save(null, { useMasterKey: true }).then(function() {
        adminRole.getUsers().add(request.user);
        adminRole.save(null, { useMasterKey: true }).then(function() {
            console.log("Role created " + adminRole.id);
            // Create Sync Status objects
            let masterSyncStatus = { user: user, syncStatus: true };
            let newUserSyncStatus = { user: user, syncStatus: true };
            let masterArray = [];
            let newUserArray = [];
            masterArray.push(masterSyncStatus);
            newUserArray.push(newUserSyncStatus);
            // Initialize Sync Status class object by groupID
            let SyncStatus = Parse.Object.extend("SyncStatus");
            let syncStatus = new SyncStatus();
            syncStatus.set("groupName", "Group_" + user);
            syncStatus.set("masterSyncStatus", masterArray);
            syncStatus.set("newUserSyncStatus", newUserArray);
            syncStatus.save(null, { useMasterKey: true }).then(function() {
                // Write own publicKey to user class
                let UserAddPublicKey = Parse.Object.extend("_User");
                let userAddPublicKey = new UserAddPublicKey();
                userAddPublicKey.set("objectId", request.user.id);
                userAddPublicKey.save(null, { useMasterKey: true }).then(function() {
                    console.log("Save success");
                });
            });
        });
    });
});