Skip to content

Commit 365df10

Browse files
Changes as per review
LF-2985
1 parent c62598f commit 365df10

File tree

4 files changed

+61
-28
lines changed

4 files changed

+61
-28
lines changed

README.md

+10-4
Original file line numberDiff line numberDiff line change
@@ -75,13 +75,19 @@ where:
7575
fhirpath.resolveInternalTypes().
7676
* options.traceFn - An optional trace function to call when tracing.
7777
* options.userInvocationTable - a user invocation table used
78-
to replace any existing or define new functions.
78+
to replace any existing functions or define new ones.
7979
* options.async - defines how to support asynchronous functions:
80-
false or similar to false, e.g. undefined, null, or 0 (default) - throw an exception,
81-
true or similar to true - return Promise, only for asynchronous functions,
82-
"always" - return Promise always.
80+
* false or similar to false, e.g. undefined, null, or 0 (default) - throw
81+
an exception,
82+
* true or similar to true - return Promise, only for asynchronous functions,
83+
* "always" - return Promise always.
8384
* options.terminologyUrl - a URL that points to a FHIR RESTful API that is
8485
used to create %terminologies that implements the Terminology Service API.
86+
* options.terminologyUrl - a URL that points to a terminology server. This
87+
URL is used to initialize %terminologies, as defined in the FHIR FHIRPath
88+
[Terminology Service API](https://www.hl7.org/fhir/fhirpath.html#txapi).
89+
See the [Implementation Status](#implementation-status) section for the
90+
currently supported %terminologies APIs.
8591

8692
Note: The resource will be modified by this function to add type information.
8793

src/additional.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,14 @@ engine.memberOf = function (coll, valueset ) {
2727

2828
if (typeof valueset === 'string' && /^https?:\/\/.*/.test(valueset)) {
2929
const terminologies = this.processedVars.terminologies;
30+
if (!terminologies) {
31+
throw new Error("Option \"termologyUrl\" is not specified.");
32+
}
3033
return Terminologies.validateVS(
3134
[terminologies], valueset, util.valData(coll[0]), ''
3235
).then(params => {
3336
return params.parameter.find((p) => p.name === "result").valueBoolean;
34-
});
37+
}, () => []);
3538
}
3639

3740
// If the valueset cannot be resolved as an uri to a value set,

src/terminologies.js

+31-16
Original file line numberDiff line numberDiff line change
@@ -63,15 +63,36 @@ class Terminologies {
6363
{ method: "POST", headers: myHeaders, body: JSON.stringify(parameters) }
6464
);
6565
} else if (typeof coded === "string") {
66-
const queryParams = new URLSearchParams({
66+
const queryParams1 = new URLSearchParams({
6767
url: valueset,
68-
code: coded,
69-
inferSystem: true
7068
});
69+
// Workaround for the case where we don't have a system. See discussion here:
70+
// https://chat.fhir.org/#narrow/stream/179266-fhirpath/topic/Problem.20with.20the.20.22memberOf.22.20function.20and.20R4.20servers
7171
response = fetch(
72-
`${requestUrl}?${queryParams.toString() + (params ? '&' + params : '')}`,
73-
{ headers: myHeaders }
74-
);
72+
`${self[0].terminologyUrl}/ValueSet?${queryParams1.toString() + (params ? '&' + params : '')}`,
73+
{headers: myHeaders}
74+
)
75+
.then(r => r.json())
76+
.then((bundle) => {
77+
const system = bundle?.entry?.length === 1 && (
78+
bundle.entry[0].resource.compose?.include?.length === 1
79+
&& bundle.entry[0].resource.compose.include[0].system
80+
|| bundle.entry[0].resource.expansion?.contains?.length === 1
81+
&& bundle.entry[0].resource.expansion?.contains[0].system);
82+
if (system) {
83+
const queryParams2 = new URLSearchParams({
84+
url: valueset,
85+
code: coded,
86+
system
87+
});
88+
return fetch(
89+
`${requestUrl}?${queryParams2.toString() + (params ? '&' + params : '')}`,
90+
{ headers: myHeaders }
91+
);
92+
} else {
93+
throw new Error('The valueset does not have a single code system.');
94+
}
95+
});
7596
} else {
7697
if (coded.code) {
7798
const queryParams = new URLSearchParams({
@@ -91,17 +112,11 @@ class Terminologies {
91112
// to do the conversion.
92113
return Promise.resolve(response)
93114
.then(r => r.json())
94-
.then(resultJson => {
95-
if (response) {
96-
let params = resultJson;
97-
if (params && params.parameter) {
98-
return params;
99-
}
100-
let outcomeResult = resultJson;
101-
if (outcomeResult && outcomeResult.issue) {
102-
throw outcomeResult;
103-
}
115+
.then(params => {
116+
if (params?.parameter) {
117+
return params;
104118
}
119+
throw new Error(params);
105120
})
106121
.catch(() => {
107122
const key = createIndexKeyMemberOf(coded, valueset);

test/async-functions.test.js

+16-7
Original file line numberDiff line numberDiff line change
@@ -54,26 +54,35 @@ describe('Async functions', () => {
5454
})
5555
});
5656

57-
/*
58-
// TODO: This unit test works only with the third-party server
59-
// (see the terminologyUrl option below). Also I posted a question here:
60-
// https://chat.fhir.org/#narrow/stream/179266-fhirpath/topic/Problem.20with.20the.20.22memberOf.22.20function.20and.20R4.20servers
6157
it('should work with Code when async functions are enabled', (done) => {
62-
6358
let result = fhirpath.evaluate(
6459
resource,
6560
"Observation.code.coding.code[0].memberOf('http://hl7.org/fhir/ValueSet/observation-vitalsignresult')",
6661
{},
6762
model,
68-
{ async: true, terminologyUrl: "https://r4.ontoserver.csiro.au/fhir" }
63+
{ async: true, terminologyUrl: "https://lforms-fhir.nlm.nih.gov/baseR4" }
6964
);
7065
expect(result instanceof Promise).toBe(true);
7166
result.then((r) => {
7267
expect(r).toEqual([true]);
7368
done();
7469
})
7570
});
76-
*/
71+
72+
it('should return an empty result when the ValueSet cannot be resolved', (done) => {
73+
let result = fhirpath.evaluate(
74+
resource,
75+
"Observation.code.coding.code[0].memberOf('http://unknown-valueset')",
76+
{},
77+
model,
78+
{ async: true, terminologyUrl: "https://lforms-fhir.nlm.nih.gov/baseR4" }
79+
);
80+
expect(result instanceof Promise).toBe(true);
81+
result.then((r) => {
82+
expect(r).toEqual([]);
83+
done();
84+
})
85+
});
7786

7887
it('should throw an exception when async functions are disabled', () => {
7988

0 commit comments

Comments
 (0)