src/applications/mhv-medications/api/rxApi.js
import {
apiRequest,
environment,
} from '@department-of-veterans-affairs/platform-utilities/exports';
import { filterOptions, INCLUDE_IMAGE_ENDPOINT } from '../util/constants';
import mockData from '../tests/e2e/fixtures/listOfPrescriptions.json';
const apiBasePath = `${environment.API_URL}/my_health/v1`;
const headers = {
'Content-Type': 'application/json',
};
/**
* Helper function to create a delay
*/
const delay = ms => {
return new Promise(resolve => setTimeout(resolve, ms));
};
/**
* Testable implementation.
* @see {@link apiRequestWithRetry} for more information
* @param {*} retryInterval how long to wait between requests
* @param {*} apiRequestFunc the API function to call; can be mocked for tests
* @returns
*/
export const testableApiRequestWithRetry = (
retryInterval,
apiRequestFunc,
) => async (path, options, endTime) => {
if (Date.now() >= endTime) {
throw new Error('Timed out while waiting for response');
}
const response = await apiRequestFunc(path, options);
// Check if the status code is 202 and if the retry time limit has not been reached
if (response?.status === 202 && Date.now() < endTime) {
await delay(retryInterval);
return testableApiRequestWithRetry(retryInterval, apiRequestFunc)(
path,
options,
endTime,
);
}
return response;
};
/**
* Recursive function that will continue polling the provided API endpoint if it sends a 404 response.
* At this time, we will only get a 404 if the patient record has not yet been created.
* @param {String} path the API endpoint
* @param {Object} options headers, method, etc.
* @param {number} endTime the cutoff time to stop polling the path and simply return the error
* @returns
*/
const apiRequestWithRetry = async (path, options, endTime) => {
return testableApiRequestWithRetry(2000, apiRequest)(path, options, endTime);
};
export const getAllergies = async () => {
return apiRequestWithRetry(
`${apiBasePath}/medical_records/allergies`,
{ headers },
Date.now() + 90000, // Retry for 90 seconds
);
};
export const getDocumentation = (id, ndcNumber) => {
return apiRequest(
`${apiBasePath}/prescriptions/${id}/documentation?ndc=${ndcNumber}`,
{
method: 'GET',
headers,
},
);
};
// **Remove once filter feature is developed and live.**
export const getPaginatedSortedList = (pageNumber = 1, sortEndpoint = '') => {
return apiRequest(
`${apiBasePath}/prescriptions?page=${pageNumber}&per_page=20${sortEndpoint}`,
{ headers },
);
};
export const getFilteredList = async filterOption => {
async function delayedReturn(value, ms) {
await delay(ms);
return value;
}
const modifyMockData = rxName => {
const mockData1 = { ...mockData };
mockData1.data[0].attributes.prescriptionName = rxName;
return mockData1;
};
switch (filterOption) {
case filterOptions.ALL_MEDICATIONS.label: {
// delayed to mimic api fetch lag
return delayedReturn(modifyMockData('all medications'), 1000);
}
case filterOptions.ACTIVE.label: {
return delayedReturn(modifyMockData('active'), 1000);
}
case filterOptions.RECENTLY_REQUESTED.label: {
return delayedReturn(modifyMockData('recently requested'), 1000);
}
case filterOptions.RENEWAL.label: {
return delayedReturn(modifyMockData('renewal'), 1000);
}
case filterOptions.NON_ACTIVE.label: {
return delayedReturn(modifyMockData('non active'), 1000);
}
default:
return mockData;
}
};
export const getRefillablePrescriptionList = () => {
return apiRequest(
`${apiBasePath}/prescriptions/list_refillable_prescriptions`,
{ headers },
);
};
export const getPrescriptionImage = cmopNdcNumber => {
return apiRequest(
`${apiBasePath}/prescriptions/get_prescription_image/${cmopNdcNumber}`,
{ headers },
);
};
export const getPrescriptionSortedList = (
sortEndpoint,
includeImage = false,
) => {
return apiRequest(
`${apiBasePath}/prescriptions?${sortEndpoint}${
includeImage ? INCLUDE_IMAGE_ENDPOINT : ''
}`,
{ headers },
);
};
export const getPrescription = id => {
return apiRequest(`${apiBasePath}/prescriptions/${id}`, { headers });
};
export const fillRx = id => {
return apiRequest(`${apiBasePath}/prescriptions/${id}/refill`, {
method: 'PATCH',
headers,
});
};
export const fillRxs = ids => {
const idParams = ids.map(id => `ids[]=${id}`).join('&');
const url = `${apiBasePath}/prescriptions/refill_prescriptions?${idParams}`;
const requestOptions = {
method: 'PATCH',
headers,
};
return apiRequest(url, requestOptions);
};