Creating bulk patients via REST

Hi all,

I’m trying to create build patients via REST and javascript.I have read https://wiki.openmrs.org/display/docs/Create+Patient and according to the docs to create a patient I first have to create a person and use the uuid of the created person to create a patient. That was easy when saving creating one patient. Now I want to create a bulk of patients in an array. My javascript code looks something like this

var patients = [] // array of patient objects to be created

// I defined my patient object to be something like
/*
   patient = {
       address: {
           address1: "Town one",
           address2: "Town two",
       },
       identifiers: [
           {
               identifier: "123",
               identifierType: "uuid",
               location: "Unknown",
               preferred: true
           }
       ], 
       person: {
           birthdate: "2017-06-11",
           gender: "M",
           names: [
               {
                   familyName: "Doe",
                   givenName: "John"
               }
           ]
       }
   }
*/
var post = function(theUrl, theData, callback) {
      $.ajax({
        type: "POST",
        url: theUrl,
        data: theData,
        success: callback,
        contentType: "application/json"
    });
}

var createPatient = function(patient) {
  // patient created
}

var saveAddress = function(address) {
  // address saved
}

 var createPerson = function(person) {
    // use person uuid to add address and create patient
    // get address stored inside localStorage
    var address = localStorage.getItem('address');
    post("/openmrs/ws/rest/v1/person/" + person.uuid,  address, saveAddress);

    // get identifiers stored in localStorage and construct patient json data for post
    var identifiers = localStorage.getItem();
    var patient = {};
    patient.person = person.uuid;
    patient.identifiers = JSON.parse();
    post("/openmrs/ws/rest/v1/patient", JSON.stringify(patient), createPatient);
}
// save all patients in array
for (var i = 0;i < patients.length;i++) {
    var person = patients[i].person;
    localStorage.setItem('identifiers', patients[i].identifiers); // will need it later inside createPerson() but not sure how to pass it as a parameter to it since it's a call back function for a post event
    localStorage.setItem('address', patients[i].address); // same reason as above
    post("/openmrs/ws/rest/v1/person", JSON.stringify(person), createPerson);
}

When I first wrote this code, my assumption was that for every value of i, I will have the following function calls

post -> createPerson -> saveAddress -> createPatient

But instead for each value of i only the first post is called and the call backs are only called after the loop has finished executing, for example if I have 3 patients in my array, I will have the following call backs

post -> post -> post ->createPerson…

Due to this error, the code correctly creates the person objects but only creates a patient for the first one. I’m fairly new to javascript and will appreciate all the help I can get to solve this.

@pris123, I did not read the rest of your post, but the documentation you have read is (very) out of date. You do not need to create a person and then a patient in two separate POSTs.

(This was changed in 2013 in [RESTWS-371] - OpenMRS Issues)

@darius thanks. Can you please help me with an example of creating a patient with a single POST. I looked the merged pull request and also the webservices.rest module. But I’m not very familiar with openmrs backend code and it’s conventions so I can’t easily see how I’ll create a patient with one POST. How will the request body look like?

Is this of any help? https://github.com/openmrs/openmrs-module-webservices.rest/blob/master/omod-1.9/src/test/java/org/openmrs/module/webservices/rest/web/v1_0/controller/openmrs1_9/PatientController1_9Test.java#L102-L116

@dkayiwa that was really helpful. I was able to create a patient using POST and the following json data

{“identifiers”: [{ “identifier”: “1122”, “identifierType”: “8d79403a-c2cc-11de-8d13-0010c6dffd0f”, “location”: “8d6c993e-c2cc-11de-8d13-0010c6dffd0f”, “preferred”: true }], “person”: { “birthdate”: “2017-06-01”, “gender”: “M”, “names”: [{ “familyName”: “Doe”, “givenName”: “John” }] } }

That create my patient fine in one call. Now I want to create a patient with an address at the same time. How will my json look like. I already tried something like this

{“address”: {“address1”: “Town one”, “address2”: “town two”}, “identifiers”: [{ “identifier”: “1972”, “identifierType”: “8d79403a-c2cc-11de-8d13-0010c6dffd0f”, “location”: “8d6c993e-c2cc-11de-8d13-0010c6dffd0f”, “preferred”: true }], “person”: { “birthdate”: “2017-06-01”, “gender”: “F”, “names”: [{ “familyName”: “Doe”, “givenName”: “Marry” }] } }

And it didn’t work. OpenMRS complained about the address field I added. Please how can I solve this?

You could try:

{
  "person": {
    "names": [{
      "givenName": "Troy",
      "familyName": "Griffith",
    }],
    "gender": "M",
    "birthdate": "1971-4-21",
    "addresses": [{
      "preferred": true,
      "address1": "1675 Wufhok Junction",
      "cityVillage": "Zoeplej",
      "stateProvince": "SK",
      "country": "Åland Islands",
      "postalCode": "66437",
    }],
    "attributes": [{
      "attributeType": {
        "uuid": "14d4f066-15f5-102d-96e4-000c29c2a5d7", // Phone Number
      },
      "value": "(280) 461-4716",
    }]
  },
  "identifiers": [{
    "identifierType": "05a29f94-c0ed-11e2-94be-8c13b969e334", // OpenMRS ID
    "identifier": "E3RWFU9F50TD4W57LA", // valid Luhn mod 30 check digit
    "location": "8d6c993e-c2cc-11de-8d13-0010c6dffd0f", // Default Location
  }]
}

:pushpin: Remove the comments.

1 Like

Here at PIH we wrote couple pages that allows us to export and import patients records via a json file using the REST API. I thought you might find useful this code that we use to export patients records to a json file:

and then to import those patients records into a different OpenMRS instance:

Here is a sample of the type of json file we produce:

The big assumption in our case is that the metadata(concepts, encounter types, locations, …etc) is the same on the source and the destination system.

1 Like

Thanks @pascal that worked. [quote=“pascal, post:6, topic:11754”] You could try:

{ “person”: { “names”: [{ “givenName”: “Troy”, “familyName”: “Griffith”, }], “gender”: “M”, “birthdate”: “1971-4-21”, “addresses”: [{ “preferred”: true, “address1”: “1675 Wufhok Junction”, “cityVillage”: “Zoeplej”, “stateProvince”: “SK”, “country”: “Åland Islands”, “postalCode”: “66437”, }], “attributes”: [{ “attributeType”: { “uuid”: “14d4f066-15f5-102d-96e4-000c29c2a5d7”, // Phone Number }, “value”: “(280) 461-4716”, }] }, “identifiers”: [{ “identifierType”: “05a29f94-c0ed-11e2-94be-8c13b969e334”, // OpenMRS ID “identifier”: “E3RWFU9F50TD4W57LA”, // valid Luhn mod 30 check digit “location”: “8d6c993e-c2cc-11de-8d13-0010c6dffd0f”, // Default Location }] } [/quote]

@cioan thanks for the suggestion. I’ll look into it.

I’m still having issues creating bulk patients even with the new knowledge of creating a patient with a single call. This new question seems to be a javascript issue so I asked on stackoverflow but I’ll still appreciate any help I’ll get from here. Here is a link to the question https://stackoverflow.com/questions/44400507/make-a-jquery-ajax-post-inside-a-loop. If you don’t want to navigate to stackoverflow, take a look at the question below

I have a bunch of data inside a loop I’ll like to POST to the server via jquery

My code is similar to something below,

var patients = [] // contains an array of patient objects I want to POST to server

var post = function(theUrl, theData, callback){
    $.ajax({
        type: "POST",
        url: theUrl,
        data: theData,
        success: callback,
        contentType: "application/json"
    });
}

var createdPatient = function(patient){
    //patient was created
}

$('#saveAll').click(function(event) {
    for (var i = 0;i < patients.length;i++) {
        var json = JSON.stringify(patients[i]);
        post("/openmrs/ws/rest/v1/patient", json, createdPatient);
    }
});

when I run the code only the last patient is been saved to the server. How can I fix this.

Did you take time to confirm that the for loop is called the number of times you expect? And with the expected patient for each turn of the loop? If you do not know how to run that code in debug mode, you could just temporarily alert() :slight_smile:

How are you determining that one patient is getting created? Is it by looking in the OpenMRS instance or based on the count of executions of your callback function?