How to get the metadata objects from the strings.

Hi,

I need to get the metadata objects from the strings as follows,

  1. Get the Location object if the string as “location” and for a given uuid.
  2. Get the Patient object, if the string as “patient” and for a given uuid.

The actual Use case will be, I will have the type as"location" and uuid as “785s8 8955d d89c5”, So I need to get the actual object based on the given type of string.

So are there any ways in OpenMRS to get the metadata object without using the @BindParams since I need to use it in the method implementation.

Cc : @dkayiwa

I do not understand the practical use case.

Actually, I’m going to store the UUID of the Location object to the person attribute. After that, when I get the value from the person attribute, I can get only the UUID. I can’t get the location Object since I don’t know which Object is releated for this UUID (may be location or role or patient …). So I need to map that object with the string (eg : “location”) to get the location object.

There will be a config file with the objectType and Object uuid.

Eg :

  1. { objectType : “location”, uuid : “45789 895cs fd855 dsf89” }
  2. { objectType : “role”, uuid : “45789 895cs fd855 dsf89” }
  3. { objectType : “patient”, uuid : “45789 895cs fd855 dsf89” }
  4. etc…

Here I need to get that actual Location or role or patient object using the uuid. So I need a way to get this.

@dkayiwa

Am still confused because my understanding is that you know the person attribute type to store the location. And this value is a uuid which you can use to get the location.

Yes,

Actually other users can use the person attribute to store the uuid of multiple objects (Can be location, patient,…) and they will point that by a string like { objectType : “location” } in their extension configs.

So I can use the IF statements to get this actual object as follows,

if( ObjectType == 'location') {
 Context.getLocationService().getLocationByUuid(uuid);
}
else if( ObjectType == 'patient') {
 Context.getPatientService().getPatientByUuid(uuid);
}
else if( ObjectType == 'person') {
 Context.getPersonService().getPersonByUuid(uuid);
}

Anyhow, I can’t write the if statements for all metadata objects in OpenMRS. SO I wanted to know If there are any methods which can convert this string to objects?

Why do you use the same person attribute type to store different objects? Isn’t this unnecessarily complicating things?

No @dkayiwa

I’m implementing common extension support for account management. So users can use the personAttribute type to customize the account creation dashboard.

So some users can use the location object as the person attribute. So the person attribute value will be location uuid. Some other users can use the role object as the person attribute. So the person attribute value will be role uuid.

When I fetch those person attribute again, I will get only the UUIDs from the person attribute (No information about the object). So I need to use the Configuration mapping to find the actual object of that uuid which fetched from that person attribute. So I wannted to know, are there any mapping functions to get the meta data object from the string.

I need to get if,

  • string=“location”, locationUUID -> location object
  • string=“role”, roleUUID -> role object
  • string=“patient”, patientUUUID -> patient object.

I think i would need real world examples to fully understand what you are doing.

Let’s think about it

I’m creating an extension to load a custom fragment which contains a selector to select the locations. When the user selects the location using that selector, that selected location uuid will be stored as a person Attribute for that person. Extension as follows, { className : "location", .......}

Another user created an extension to load another custom fragment which contains a selector to select the roles. When the user selects the role using that selector, that selected role uuid will be stored as a person attribute for that person. Extension as follows, { className : "role", .......}

So finally I have these following records in the database

id | value                  | personAttributeTypeId | uuid
1  | 74dfv-de458-da57-asfe5 | 4                     | 5s8ec-sa9d-cas95-asa569
2  | 78dc9-af545-sf28-89dc5 | 5                     | 58d9c-56s9-sf596-c56956

So in the database, I have only uuids as the value of those objects. Anyhow, id=1 should represent the locationUuid, and id=2 should represents the roleUuid.

When I fetch these value from the database using the personAttribute.value, I need to map this object to the original object with this uuid (value in here). So I’m using the extension configuration to map this object since I have the className information in the extension config.

So I need to map the id=1 with location class, and id=2 with role class. One way is using the IF conditions to get the actual objects like this following

if( extension.params.objectType == 'location') {
 Context.getLocationService().getLocationByUuid(uuid);
}
else if( extension.params.objectType == 'patient') {
 Context.getPatientService().getPatientByUuid(uuid);
}
else if( extension.params.objectType == 'person') {
 Context.getPersonService().getPersonByUuid(uuid);
}
{
..... }

But I can’t use the IF condtions to check for all metadata objects in the OpenMRS. So I need to check wthere, are there any methods which can map the metadata objects from the className.

Some thing similar I want like,

MethodA.getObject(string className, uuid) --> Should return the object

Eg:

 MethodA.getObject("location", "74dfv-de458-da57-asfe5") --> Should return the Location object
 MethodA.getObject("role", " 78dc9-af545-sf28-89dc5") --> Should return the Role object

So I can get anmetadatata objects through this method. Please let me know, are there any ways like this to get the actual object from the uuid and the className.

Why not let each custom extension deal with its own data storage and loading?

So then, they need to create two fragments for Add/Edit and View. If the dashboard took the view part, then the users only need to create a fragment for Add/Edit.

And if we allow the custom fragments to take the view part, It will not keep the consistency of the dashboard.

See here,

Or we need to define some restrictions for the custom view fragments to use the defined HTML elements to keep the consistency of the dashboard.

What do you think?

  1. Take the view part inside the dashboard to keep the consitenecy and reduce the number of custom fragments
  2. Allow custom view fragements with some HTML tag restrictions to keep the consistency

What would you recommend?

It would be better to take the view part inside the dashboard, and provide support for some metadata objects like Location, Person, Patient, Role, personAddress, some more(through the IF condition as mentioned above)

It is not cool to have a design which needs an if condition for each new object.

Yes, I too felt that

That’s why I asked for the alternative methods :smile:

So else can I move to option two?

I do not see any problem with having different extension points for viewing and editing.

Okay @dkayiwa let me do it in that way.