Cortex Objects

This is a tutorial on how to handle Cortex objects in the Cortex Android SDK

The Cortex SDK makes it easy to work with your custom object in your mobile app. Below are examples on how to do so with the example custom prescription object, c_prescription, created in the Data Model Setup guide.

1. Creating the custom class

First, we need to create a custom class for our new custom prescription object as a subclass of ObjectInstance. ObjectInstance is the base class to model any custom object instance in Cortex.

The prescription class implementation, would look something like the following:

public class Prescription extends ObjectInstance {

    protected Prescription(JsonObject attributes) {
        super(attributes);
    }

    Date getDate() {
        return this.dateValueWithPropertyName("c_date");
    }

    Number getDispense() {
        return this.numberValueWithPropertyName("c_dispense");
    }

    Reference getPatient() {
        return this.referenceValueWithPropertyName("c_patient");
    }

    Reference getProvider() {
        return this.referenceValueWithPropertyName("c_provider");
    }
    
    Number getRefills() {
        return this.numberValueWithPropertyName("c_refills");
    }

    String getDetails() {
        return this.stringValueWithPropertyName("c_rx");
    }

}
class Prescription(attributes: JsonObject) : ObjectInstance(attributes) {

    internal val date: Date?
        get() = this.dateValueWithPropertyName("c_date")

    internal val dispense: Number?
        get() = this.numberValueWithPropertyName("c_dispense")

    internal val patient: Reference?
        get() = this.referenceValueWithPropertyName("c_patient")

    internal val provider: Reference?
        get() = this.referenceValueWithPropertyName("c_provider")

    internal val refills: Number?
        get() = this.numberValueWithPropertyName("c_refills")

    internal val details: String?
        get() = this.stringValueWithPropertyName("c_rx")

}

2. Registering the new object

Now that we have a new custom class Prescription we want to use for the c_prescription object instances, let's register it by doing the following:

APIClient.sharedInstance().registerContextClass("c_prescription","c_prescriptions", null, Prescription.class);
APIClient.sharedInstance().registerContextClass("c_prescription", "c_prescriptions", null, Prescription::class.java)

Now, whenever you query routes that return c_prescription instances, Cortex will return instances of your custom class Prescription:

APIClient.sharedInstance().listObjects("c_prescriptions", null, new ObjectsListCallback<ObjectInstance>() {
            @Override
            public void call(List<ObjectInstance> results, boolean hasMore, Fault fault) {
                List<Prescription> prescriptions = (List) results;
            }
        });
APIClient.sharedInstance().listObjects("c_prescriptions", null) { results, hasMore, fault ->
            val prescriptions = results as List<Prescription>
        }

This also works for expanded references to related objects you have registered.

For example, if in another custom object you have a reference property named c_prescription that relates to the c_prescription object and you query that custom object with expand=c_prescription, then the Reference @ expandedObjectReference will also be an instance of Prescription automagically.

APIParameters expandedPrescription = APIParameterFactory.parametersWithExpandPaths(null, "c_prescription");
ObjectId identifier = new ObjectId("...");
      
APIClient.sharedInstance().getObject("c_someOtherCustomObjectWithAReferenceToAPrescription", identifier, expandedPrescription, new ObjectFaultCallback<ObjectInstance>() {
            @Override
            public void call(ObjectInstance object, Fault fault) {
                Reference referenceToPrescription = object.referenceValueWithPropertyName("c_prescription");
                Prescription myPrescriptionInstance = (Prescription) referenceToPrescription.getExpandedObjectReference();
            }
        });
val expandedPrescription = APIParameterFactory.parametersWithExpandPaths(null, "c_prescription")
val identifier = ObjectId("...")
        
APIClient.sharedInstance().getObject("c_someOtherCustomObjectWithAReferenceToAPrescription", identifier, expandedPrescription) { `object`, fault ->
            val referenceToPrescription = `object`.referenceValueWithPropertyName("c_prescription")
            val myPrescriptionInstance = referenceToPrescription!!.expandedObjectReference as Prescription
        }

3. Using custom objects with different types

In Cortex, you can create a custom context and subclass it by using types. In this case the object name will be the same for both custom classes, however they will differ in type.

Let's suppose you have two types of prescriptions, both share all the same base properties but each one has additional properties only usable on each type of prescription.

For the simplicity's sake, let's suppose that we have two types of prescriptions, "A" and "B". PrescriptionA has all the properties from Prescription plus prescriptionAProperty, and PrescriptionB has all the properties from Prescription plus prescriptionBProperty...

You'd accomplish this in your app in the following manner:

  1. Create a PrescriptionA class that is a subclass of Prescription and add the prescriptionAProperty to the class.
public class PrescriptionA extends Prescription {

    protected PrescriptionA(JsonObject attributes) {
        super(attributes);
    }

    String getPrescriptionAProperty() {
        return stringValueWithPropertyName("c_prescriptionAProperty");
    }
}
class PrescriptionA (attributes: JsonObject) : Prescription(attributes) {

    internal val prescriptionAProperty: String?
        get() = stringValueWithPropertyName("c_prescriptionAProperty")
}
  1. Create a PrescriptionB class that is a subclass of Prescription and add the prescriptionBProperty to the class.
public class PrescriptionB extends Prescription {

    protected PrescriptionB(JsonObject attributes) {
        super(attributes);
    }

    String getPrescriptionAProperty() {
        return stringValueWithPropertyName("c_prescriptionBProperty");
    }
}
class PrescriptionB (attributes: JsonObject) : Prescription(attributes) {

    internal val prescriptionBProperty: String?
        get() = stringValueWithPropertyName("c_prescriptionBProperty")
}
  1. Then register both classes using the same context c_prescription while specifying the appropriate type.
APIClient.sharedInstance().registerContextClass("c_prescription","c_prescriptions", "c_A", PrescriptionA.class);
APIClient.sharedInstance().registerContextClass("c_prescription","c_prescriptions", "c_B", PrescriptionB.class);
APIClient.sharedInstance().registerContextClass("c_prescription", "c_prescriptions", "c_A", PrescriptionB::class.java)
APIClient.sharedInstance().registerContextClass("c_prescription", "c_prescriptions", "c_B", PrescriptionB::class.java)