How do I POST a record and then immediately Read/GET the record I just posted?

I have code that GETs records from APP 36 (called Payers) where the "'Add_for_New_Practitioner" field equals "Yes".

Then I GET records from APP 12 (Practitioners) where the "new flag" is equal to "Yes".

Then, I POST one record to APP 31 (Practitioners Payers) for each combination of payers and practitioners. (For example, if I have 2 new practitioners and 3 payers where the "'Add_for_New_Practitioner" field equals "Yes", I get 3 payer records for each practitioner for a total of 6 "Practitioners Payers" records.)

This part works great. However, the next step is to create a task record for each of the newly created "Practitioners Payers" records. I cannot get the task records to create because, I assume, the "Practitioners Payers" records aren't physically saved yet when the code executes to read them.

I am seeking help with the code that will save the "Practitioners Payers" records before I attempt to GET them for the next step. Below is my current code. Any guidance will be greatly appreciated.

(function() {
    'use strict';

    // create button
    let SPACE = 'Add_All_Payers_Btn'; // element ID of Blank Space field

    kintone.events.on(['app.record.create.show', 'app.record.edit.show'], function(event) {
        let btn = document.createElement('button');
        btn.textContent = 'Add All Payers';
        kintone.app.record.getSpaceElement(SPACE).appendChild(btn);

        // on click, confirm that user truly wants to create the practitioner payer records
        // if yes, then execute the code to create all practitioner payer records and task records
        btn.onclick = function() {
            let userInput = prompt('All payers and portals will be added for all newly imported practitioners. Do you want to continue? (Yes or No)');
            if (userInput.toLowerCase() === 'yes') {
                console.log('User confirmed action.');
                triggerSave().then(() => {
                    fetchAndProcessRecords().then(() => {
                        setTimeout(() => {
                            window.location.reload(); // Refresh page after updates
                        }, 1000); // Delay to ensure updates are processed by the server
                    });
                });

                // write a task record for each payer/portal record that was just created
                console.log("Next Up: write task records");
                writeTaskRecords().then(() => {
                    setTimeout(() => {
                        window.location.reload(); // Refresh page after updates
                    }, 1000);  // Delay to ensure updates are processed by the server
                });
            }
        };
        return event;
    });

    function fetchAndProcessRecords() {
        // Get all records from LV Payer/Portal app where the Payer/Portal is flagged to add for newly imported practitioners
        return fetchRecords(36, 'Add_for_New_Practitioner in ("Yes") order by $id asc limit 100', ['$id', 'Payer_Portal_Name'])
            .then(payersPortals => {
                if (payersPortals.length === 0) {
                    console.log('No payers or portals to process.');
                    return; // Stop further processing if no practitioners are found
                }
                console.log('Payer/Portal Records:', payersPortals);
                console.log("Next up: displaying each value in the array of payers.");

                let arrayLength = payersPortals.length;
                console.log("Length is: " + arrayLength);

                for (let i = 0; i < arrayLength; i++) {
                    console.log("Value " + i + " is: " + payersPortals[i].Payer_Portal_Name.value);
                }

                // Get all records from Practitioner View app where the New Flag = Yes
                return fetchRecords(12, 'New_Flag_Text in ("Yes") order by $id asc limit 100', ['$id', 'practitioner_npi'])
                    .then(practitioners => {
                        if (practitioners.length === 0) {
                            console.log('No new practitioners to process.');
                            return; // Stop further processing if no practitioners are found
                        }
                        console.log('New Practitioners Records:', practitioners);

                        console.log("Next up: displaying each value in the array of practitioners.");
                        let arrayLength2 = practitioners.length;

                        for (let p = 0; p < arrayLength2; p++) {
                            console.log("Value " + p + " is: " + practitioners[p].practitioner_npi.value);
                            for (let i = 0; i < arrayLength; i++) {
                                var body = {
                                    'app': 31, // 31 is practitioners payers
                                    'record': {
                                        'Practitioner_NPI': {
                                            'value': practitioners[p].practitioner_npi.value
                                        },
                                        'Payer_or_Portal_Name': {
                                            'value': payersPortals[i].Payer_Portal_Name.value
                                        },
                                        'New_Flag': {
                                            'value': 'Yes'
                                        },
                                        'Status_Enrollment': {
                                            'value': 'New/Not Started'
                                        }
                                    }
                                };

                                // Call the function to write the Practitioner Payer/Portal record
                                writeRecord(body);
                            }
                        }
                    });
            });
    }

    function writeTaskRecords() {
        // *****  Read all new practitioner payer/portal records and create associated task records
        // Get all records from Practitioner Payer/Portal app where the New Flag = Yes

        return fetchRecords(31, 'New_Flag_Text in ("Yes") order by $id asc limit 500', ['$id', 'Practitioner_NPI', 'Payer_Portal_Name_Text', 'Record_number'])
            .then(practitionerPP => {
                if (practitionerPP.length === 0) {
                    console.log('No new practitioner payer/portal records to process.');
                    return; // Stop further processing if no practitioners are found
                }
                let arrayLength3 = practitionerPP.length;

                for (let n = 0; n < arrayLength3; n++) {
                    var body = {
                        'app': 11, // 11 is the Task app
                        'record': {
                            'Practitioner_NPI': {
                                'value': practitionerPP[n].Practitioner_NPI.value
                            },
                            'Task_Payer_Portal': {
                                'value': practitionerPP[n].Payer_Portal_Name_Text.value
                            },
                            'Linked_PayerPortal_RecID': {
                                'value': practitionerPP[n].Record_number.value
                            },
                            'Task_Association': {
                                'value': 'Payer/Portal'
                            },
                            'task_category': {
                                'value': 'New Payer/Portal Enrollment'
                            }
                        }
                    };

                    // Call the function to write the Practitioner Payer/Portal record
                    writeRecord(body);
                }
            });
        //  End of the function to write the task records
    }

    function writeRecord(body) {
        kintone.api(kintone.api.url('/k/v1/record.json', true), 'POST', body, function(resp) {
            // success
            console.log(resp);
        }, function(error) {
            // error
            console.log(error);
        });
    }

    function fetchRecords(appId, query, fields) {
        // Construct the parameters object
        const params = {
            app: appId,
            query: query,
            fields: fields
        };

        // Make the API call correctly with the API endpoint, method, and parameters
        return kintone.api(kintone.api.url('/k/v1/records.json', true), 'GET', params)
            .then(response => {
                if (response.records) {
                    return response.records;
                } else {
                    throw new Error('No records returned from the API.');
                }
            })
            .catch(error => {
                console.error('API call failed:', error);
                throw error; // Rethrow to ensure it's caught by the caller
            });
    }

    function triggerSave() {
        return new Promise(resolve => {
            var saveButton = document.querySelector('.gaia-ui-actionmenu-save');
            if (saveButton) {
                saveButton.click();
                setTimeout(() => {
                    resolve(); // Assume save is complete after a delay
                }, 1000); // Adjust delay as needed based on testing
            } else {
                resolve(); // Resolve immediately if save button isn't found (e.g., view mode)
            }
        });
    }
})();

Hello @DebraMalkus

As you mentioned, it looks like the main issue with the code is that the newly created "Practitioners Payers" records are not immediately available when trying to fetch them for creating task records.
The records need to be saved and available before the next step executes. To ensure the "Practitioners Payers" records are saved before attempting to create task records, you need to implement the following steps in your script:

Steps to Follow:

  1. Use Promises for Asynchronous Processing:
    When making your API calls to create "Practitioners Payers" records, ensure that each call returns a promise. This allows you to wait for each operation to complete before moving on to the next step.
  2. Wait for All Records to be Created:
    Use Promise.all() to handle multiple promises. This ensures that all "Practitioners Payers" records are created before you proceed to fetch them for the next step.
  3. Fetch Records After Creation:
    After confirming that all records are created, make another API call to fetch these records. This ensures that the records are saved and available for creating task records.

Example Approach:

  1. Creating Practitioner Payer Records:
    -Use a loop to create records and push each kintone.api() call into an array of promises.
    -Wait for all promises to resolve using Promise.all().
  2. Fetching Newly Created Records:
    -Once all records are created, make a new API call to fetch the saved records.
    -Use the fetched records to create the corresponding task records.

Thank you Chris. Your approach makes sense. I'll give it a try.

1 Like

Hey Chris,
I added the code I thought would work but no luck. I get the console message stating that the records saved successfully but I immediately get the next message that "no new practitioner payer/portal records to process." It's just not waiting for the records to be written before it executes the command to Get/Read.

Here's a screen shot of the console log.
image

My code is below. Could you take a look and see if you can identify what I am missing?
Thanks!

(function() {
'use strict';

let SPACE = 'Add_All_Payers_Btn'; // element ID of Blank Space field

kintone.events.on(['app.record.create.show', 'app.record.edit.show'], function(event) {
    let btn = document.createElement('button');
    btn.textContent = 'Add All Payers';
    kintone.app.record.getSpaceElement(SPACE).appendChild(btn);

    btn.onclick = function() {
        let userInput = prompt('All payers and portals will be added for all newly imported practitioners. Child payers will not be added at this time. Do you want to continue? (Yes or No)');
        if (userInput.toLowerCase() === 'yes') {
            console.log('User confirmed action.');
            triggerSave().then(() => {
                fetchAndProcessRecords().then(() => {  
                    setTimeout(() => {
                        window.location.reload(); // Refresh page after updates
                    }, 1000);                         
                });
             });
        }
    };
    return event;
});

function fetchAndProcessRecords() {
    console.log('Initiating process to add records...');
    
    // Get all records from LV Payer/Portal app where the Payer/Portal is flagged to add for newly imported practitioners
    return fetchRecords(36, 'Add_for_New_Practitioner in ("Yes") order by $id asc limit 100', ['$id','Payer_Portal_Name'])
        .then(payersPortals => {
            if (payersPortals.length === 0) {
                console.log('No payers or portals to process.');
                return; // Stop further processing if no practitioners are found
            }
            console.log('Payer/Portal Records:', payersPortals);
            console.log("Next up: displaying each value in the array of payers.");

            let arrayLength = payersPortals.length;
            console.log("Length is: " + arrayLength);
            
            for (let i = 0; i < arrayLength; i++){
               console.log("Value " + i + " is: " + payersPortals[i].Payer_Portal_Name.value);   
            }
        //});
        
    // Get all records from Practitioner View app where the New Flag = Yes
    return fetchRecords(12, 'New_Flag_Text in ("Yes") order by $id asc limit 100', ['$id','practitioner_npi'])
        .then(practitioners => {
            if (practitioners.length === 0) {
                console.log('No new practitioners to process.');
                return; // Stop further processing if no practitioners are found
            }
            console.log('New Practitioners Records:', practitioners);
            
            console.log("Next up: displaying each value in the array of practitioners.");
            let arrayLength2 = practitioners.length;
            
            console.log("Length2 is: " + arrayLength2);
            
            // Array to store promises   6/12/24
            const promises = [];      //6/12/24
            
            for (let p = 0; p < arrayLength2; p++){   // 1 open
              console.log("Value " + p + " is: " + practitioners[p].practitioner_npi.value);  
                 for (let i = 0; i < arrayLength; i++){   // 2 open
                      var body = {   // 3 open
                      'app': 31,     // 'app': 37,  // 31 is production app and 37 is test app
                      'record': {   // 4 open
                          'Practitioner_NPI': {    // 5 open
                          'value': practitioners[p].practitioner_npi.value
                        },   // 5 close
                        'Payer_or_Portal_Name': {  // 6 open
                          'value': payersPortals[i].Payer_Portal_Name.value   
                      },    // 6 close
                        'New_Flag':{
                          'value': 'Yes'
                      },
                          'Status_Enrollment': {  // 6a open
                          'value': 'New/Not Started'   
                      }    // 6a close
                      }    // 4 close   New/Not Started
                    };  // 3 close

          // Call the function to write the Practitioner Payer/Portal record
                      const promise = writeRecord(body);    // 6/12/24
                      promises.push(promise);               // 6/12/24
                      // Wait for all promises to resolve using Promise.all() 
                 }   // 2 close
              
            }   // 1 close

                      // confirm all promises are complete before moving to next step    // 6/12/24
                      Promise.all(promises)                   // 6/12/24
                      .then((savedRecords) => {               // 6/12/24
                      console.log('All records saved successfully:', savedRecords);      // 6/12/24
                      })   // 6/12/24
                      .then(writeTaskRecords) // 6/12/24   removed from above and put here
                      .catch((error) => {                     // 6/12/24
                      console.error('Error saving records:', error);    // 6/12/24
                      });
                      // end of "confirm all promises are complete before moving to next step"    // 6/12/24
        });  

});
}

// function to write the task records
function writeTaskRecords() { // open function
// ***** Read all new practitioner payer/portal records and create an associated task records
// Then set new_flag on practitioner payer/portal records to No
// Get all records from Practitioner Payer/Portal app where the New Flag = Yes

    return fetchRecords(31, 'New_Flag_Text in ("Yes") order by $id asc limit 500', ['$id','Practitioner_NPI','Payer_Portal_Name_Text','Record_number'])
        .then(practitionerPP => {   // a open
            if (practitionerPP.length === 0) {   // b open
                console.log('No new practitioner payer/portal records to process.');
                return; // Stop further processing if no practitioners are found
            }  // b close
            console.log('New Practitioner Payer/Portal Records:', practitionerPP);
            
            console.log("Next up: displaying each value in the array of practitioner payer/portal records and creating a task record for each.");
            let arrayLength3 = practitionerPP.length;
            
            console.log("Length3 is: " + arrayLength3);
            
            for (let n = 0; n < arrayLength3; n++){   // 1 open
              console.log("Value " + n + " is: " + practitionerPP[n].Practitioner_NPI.value + " PP: " + practitionerPP[n].Payer_Portal_Name_Text.value + "Rec Id: " + practitionerPP[n].Record_number.value);  
                 
                      var body = {   // 3 open
                      'app': 11,   // 11 is the Task app    
                      'record': {   // 4 open
                          'Practitioner_NPI': {    // 5 open
                          'value': practitionerPP[n].Practitioner_NPI.value
                        },   // 5 close
                        'Task_Payer_Portal': {  // 6 open
                          'value': practitionerPP[n].Payer_Portal_Name_Text.value   
                      },    // 6 close
                        'Linked_PayerPortal_RecID':{    // 7 open
                          'value': practitionerPP[n].Record_number.value   
                      }, // 7 close
                        'Task_Association':{   // 8 open
                          'value': 'Payer/Portal' 
                      }, // 8 close
                        'task_category': {   // 9 open
                          'value': 'New Payer/Portal Enrollment'
                      } // 9 close
                      } // 4 close   
                    };  // 3 close
          // Call the function to write the Practitioner Payer/Portal record
                      writeRecord(body);
           }  // 1 close
          });   // a close

// End of the function to write the task records

}
function writeRecord(body) {
kintone.api(kintone.api.url('/k/v1/record.json', true), 'POST', body, function(resp) {
// success
console.log(resp);
}, function(error) {
// error
console.log(error);
});
}

function fetchRecords(appId, query, fields) {
  // Construct the parameters object
  const params = {
    app: appId,
    query: query,
    fields: fields
  };

  // Make the API call correctly with the API endpoint, method, and parameters
  return kintone.api(kintone.api.url('/k/v1/records.json', true), 'GET', params)
    .then(response => {
      if (response.records) {
        return response.records;
      } else {
        throw new Error('No records returned from the API.');
      }
    })
    .catch(error => {
      console.error('API call failed:', error);
      throw error; // Rethrow to ensure it's caught by the caller
    });
}   

  function triggerSave() {
    return new Promise(resolve => {
        var saveButton = document.querySelector('.gaia-ui-actionmenu-save');
        if (saveButton) {
            saveButton.click();
            setTimeout(() => {
                resolve(); // Assume save is complete after a delay
            }, 1000); // Adjust delay as needed based on testing
        } else {
            resolve(); // Resolve immediately if save button isn't found (e.g., view mode)
        }
    });
}   

})();

Helllo @DebraMalkus
I reviewed the script, but I'm not entirely sure what the issue might be. Utilizing async/await might be beneficial, as it's noted as another method of asynchronous processing on the same page. Here's an example script that incorporates async/await:

(function() {
   "use strict";

   // Declare async at the beginning of the function.
   kintone.events.on(['app.record.create.show', 'app.record.edit.show'], async function(event) {

      var getbody = {
         'app': 'appid' // Replace with your app id
      };

      // Declare await where you want to wait for the process
      var resp_get = await kintone.api(kintone.api.url('/k/v1/records.json', true), 'GET', getbody);
      // Display the retrieved value on the console screen
      console.log(resp_get);
      
      var postbody = {
         'app': 'appid', // Replace with your app id
         'record':{
             'Text':{
                 'value' : resp_get.records[0].$id.value
             }
         }
      };

      // Declare await where you want to wait for the process
      var resp_post = await kintone.api(kintone.api.url('/k/v1/record.json', true), 'POST', postbody);
      // Display the retrieved value on the console screen
      console.log(resp_post);
   });
})();