Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add AbortSignal to OpenSRPServer service #625

Closed
wants to merge 25 commits into from
Closed
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
b73a191
Add abort signal parameter to opensrpservice
peterMuriuki Dec 16, 2019
a03c96b
Add the abort signal to Practitioner view api calling funcs
peterMuriuki Dec 16, 2019
73fa70d
Add cleanup to createEditPractitioner aborting pending fetch's
peterMuriuki Dec 16, 2019
c232cbf
Add cleanup to PractitionerList aborting fetche's
peterMuriuki Dec 16, 2019
37e4376
Add signal param to organization views data calling funcs
peterMuriuki Dec 16, 2019
99b908f
Add cleanup to Assign Practitioners aborting fetche's
peterMuriuki Dec 16, 2019
d75fd4b
Add cleanup to create/edit org aborting fetche's
peterMuriuki Dec 16, 2019
15f060d
Add cleanup to organization listing; aborting fetche's
peterMuriuki Dec 16, 2019
a2a23c1
Add cleanup to single organization; aborting fetch
peterMuriuki Dec 16, 2019
daaede0
Add cleanup to planDefinition; aborting fetch
peterMuriuki Dec 16, 2019
3cb4eed
Add cleanup to UpdatePlan component; aborting fetch
peterMuriuki Dec 16, 2019
319b660
Add growling to updateplan component
peterMuriuki Dec 16, 2019
6d24bf6
Add cleanup to IRS assignments; aborting fetch
peterMuriuki Dec 16, 2019
64d18ea
Add growling and cleanup to organization select form component
peterMuriuki Dec 16, 2019
c93e1be
Add cleanup and growl to UserIdSelect component
peterMuriuki Dec 16, 2019
986710f
Refactor regression errors in organizationViews servicehooks
peterMuriuki Dec 16, 2019
af29459
Fix regression errors from introducing abort
peterMuriuki Dec 16, 2019
d3a19bc
Refactor cleanup function that aborts fetch
peterMuriuki Apr 14, 2020
c2c724b
Merge branch 'master' into 554-abortFetch
peterMuriuki Apr 14, 2020
abeb790
Fix linting
peterMuriuki Apr 14, 2020
16eba72
Remove abortFetch functionality from several containers
peterMuriuki Apr 16, 2020
652ac54
Only apply signal to fetch if its provided
peterMuriuki Apr 16, 2020
99cd428
remove suprlus function abortFetch
peterMuriuki Apr 16, 2020
237931c
Revert setLoading usage in Irs/assignments
peterMuriuki Apr 17, 2020
c33e1cb
Call setstaters only when component is mounted
peterMuriuki Apr 17, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/components/forms/OrganizationSelect/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ const defaultProps: OrganizationSelectProps = {
};

/**
* OrganizationSelect - a flat select for Organizations
* OrganizationSelect - a select for Organizations
* Allows you to Select Organizations to be assigned to the plan-jurisdiction
* On selection update the `handleChange` method updates the Assignments store
*/
Expand Down
10 changes: 7 additions & 3 deletions src/components/forms/PractitionerForm/UserIdSelect/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ export const UserIdSelect: React.FC<Props> = props => {
}
};

/** Pulls all openMRS users data */
/** Pulls all openMRS users data
* @param {typeof OpenSRPService} service - the opensrp service
*/
const loadOpenMRSUsers = async (service: typeof OpenSRPService = OpenSRPService) => {
let filterParams = {
page_size: OPENMRS_USERS_REQUEST_PAGE_SIZE,
Expand Down Expand Up @@ -96,8 +98,10 @@ export const UserIdSelect: React.FC<Props> = props => {
const loadUnmatchedUsers = async () => {
const practitioners: Practitioner[] = await new props.serviceClass(
OPENSRP_PRACTITIONER_ENDPOINT
).list();
const allOpenMRSUsers = await loadOpenMRSUsers();
)
.list()
.catch((err: Error) => displayError(err));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to add a test that displayError is, in fact, called?

const allOpenMRSUsers = await loadOpenMRSUsers(props.serviceClass);

const practitionerUserIds = practitioners.map(practitioner => practitioner.userId);
const unMatchedUsers = allOpenMRSUsers.filter(user => !practitionerUserIds.includes(user.uuid));
Expand Down
18 changes: 9 additions & 9 deletions src/containers/pages/IRS/assignments/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import ListView from '@onaio/list-view';
import reducerRegistry, { Registry } from '@onaio/redux-reducer-registry';
import React, { useEffect, useState } from 'react';
import React, { useEffect } from 'react';
import { Helmet } from 'react-helmet';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
Expand All @@ -22,6 +22,7 @@ import { planStatusDisplay } from '../../../../configs/settings';
import {
ASSIGN_PLAN_URL,
HOME_URL,
OPENSRP_PLANS,
PLAN_RECORD_BY_ID,
REPORT_IRS_PLAN_URL,
} from '../../../../constants';
Expand All @@ -43,21 +44,21 @@ import {
/** register the plan definitions reducer */
reducerRegistry.register(IRSPlansReducerName, IRSPlansReducer);

const OpenSrpPlanService = new OpenSRPService('plans');

/** Plans filter selector */
const plansArraySelector = makePlansArraySelector(PLAN_RECORD_BY_ID);

/** interface for PlanAssignmentsListProps props */
interface PlanAssignmentsListProps {
fetchPlans: typeof fetchPlanRecords;
plans: PlanRecord[];
service: typeof OpenSRPService;
}

/** Simple component that loads plans and allows you to manage plan-jurisdiciton-organization assignments */
/** Simple component that loads plans and allows you to manage plan-jurisdiction-organization assignments */
const IRSAssignmentPlansList = (props: PlanAssignmentsListProps) => {
const { fetchPlans, plans } = props;
const [loading, setLoading] = useState<boolean>(plans.length < 1);
const { fetchPlans, plans, service } = props;

const OpenSrpPlanService = new service(OPENSRP_PLANS);

const pageTitle: string = `${ASSIGN_PLANS}`;

Expand All @@ -77,7 +78,6 @@ const IRSAssignmentPlansList = (props: PlanAssignmentsListProps) => {
/** async function to load the data */
async function loadData() {
try {
setLoading(plans.length < 1); // only set loading when there are no plans
await OpenSrpPlanService.list()
.then(planResults => {
if (planResults) {
Expand All @@ -89,7 +89,6 @@ const IRSAssignmentPlansList = (props: PlanAssignmentsListProps) => {
.catch(err => {
displayError(err);
});
setLoading(false);
} catch (e) {
displayError(e);
}
Expand All @@ -99,7 +98,7 @@ const IRSAssignmentPlansList = (props: PlanAssignmentsListProps) => {
loadData().catch(error => displayError(error));
}, []);

if (loading) {
if (plans.length < 1) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we get 0 plans from the API, does this mean we will show the loading indicator forever?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i was thinking about this wrong. let me refactor.

return <Loading />;
}
cKellyDesign marked this conversation as resolved.
Show resolved Hide resolved

Expand Down Expand Up @@ -147,6 +146,7 @@ const IRSAssignmentPlansList = (props: PlanAssignmentsListProps) => {
const defaultProps: PlanAssignmentsListProps = {
fetchPlans: fetchPlanRecords,
plans: [],
service: OpenSRPService,
};

IRSAssignmentPlansList.defaultProps = defaultProps;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import ListView from '@onaio/list-view';
import reducerRegistry from '@onaio/redux-reducer-registry';
import React, { useEffect, useState } from 'react';
import React, { useEffect } from 'react';
import { Helmet } from 'react-helmet';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
Expand Down Expand Up @@ -41,7 +41,6 @@ interface PlanListProps {
/** Simple component that loads the new plan form and allows you to create a new plan */
const PlanDefinitionList = (props: PlanListProps) => {
const { fetchPlans, plans, service } = props;
const [loading, setLoading] = useState<boolean>(true);

const apiService = new service(OPENSRP_PLANS);

Expand All @@ -63,21 +62,18 @@ const PlanDefinitionList = (props: PlanListProps) => {
/** async function to load the data */
async function loadData() {
try {
setLoading(plans.length < 1); // only set loading when there are no plans
const planObjects = await apiService.list();
fetchPlans(planObjects);
} catch (e) {
displayError(e);
} finally {
setLoading(false);
}
}

useEffect(() => {
loadData().catch(err => displayError(err));
}, []);

if (loading === true) {
if (plans.length < 1) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we get 0 plans from the API, does this mean we will show the loading indicator forever?

return <Loading />;
}
cKellyDesign marked this conversation as resolved.
Show resolved Hide resolved

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { connect } from 'react-redux';
import { Card, CardBody, CardHeader, Collapse } from 'reactstrap';
import { ActionCreator, Store } from 'redux';
import Loading from '../../../../../components/page/Loading';
import { OPENSRP_API_BASE_URL } from '../../../../../configs/env';
import {
CASE_DETAILS,
CASE_INFORMATION,
Expand Down Expand Up @@ -60,7 +59,7 @@ const loadEvent = (
servant: typeof OpenSRPService,
actionCreator: ActionCreator<FetchEventsAction>
) => {
const service = new servant(OPENSRP_FIND_EVENTS_ENDPOINT, OPENSRP_API_BASE_URL);
const service = new servant(OPENSRP_FIND_EVENTS_ENDPOINT);
const filterParams = {
id: eventId,
};
Expand Down
8 changes: 2 additions & 6 deletions src/containers/pages/InterventionPlan/UpdatePlan/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import reducerRegistry from '@onaio/redux-reducer-registry';
import React, { useEffect, useState } from 'react';
import React, { useEffect } from 'react';
import { Helmet } from 'react-helmet';
import { connect } from 'react-redux';
import { RouteComponentProps } from 'react-router';
Expand Down Expand Up @@ -46,7 +46,6 @@ export interface RouteParams {
const UpdatePlan = (props: RouteComponentProps<RouteParams> & UpdatePlanProps) => {
const { fetchPlan, plan, service } = props;
const planIdentifier = props.match.params.id;
const [loading, setLoading] = useState<boolean>(true);

if (!planIdentifier) {
return null; /** we should make this into a better error page */
Expand All @@ -56,22 +55,19 @@ const UpdatePlan = (props: RouteComponentProps<RouteParams> & UpdatePlanProps) =
/** async function to load the data */
async function loadData() {
try {
setLoading(plan === null); // only set loading when there are no plans
const planFromAPI = await apiService.read(planIdentifier);
const currentPlan = Array.isArray(planFromAPI) ? planFromAPI[0] : planFromAPI;
fetchPlan(currentPlan);
} catch (e) {
displayError(e);
} finally {
setLoading(false);
}
}

useEffect(() => {
loadData().catch(err => displayError(err));
}, []);

if (loading === true) {
if (plan === null) {
Comment on lines -74 to +70
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why this change?

return <Loading />;
}
cKellyDesign marked this conversation as resolved.
Show resolved Hide resolved

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export type CreateEditTeamViewTypes = Props & RouteComponentProps<RouteParams>;
/** CreateEditTeamView component */
const CreateEditOrgView = (props: CreateEditTeamViewTypes) => {
const { organization, serviceClass, fetchOrganizationsCreator } = props;

// use route to know if we are editing team or creating team
const editing = !!props.match.params.id;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ const SingleOrganizationView = (props: SingleOrgViewPropsType) => {

// functions / methods //

/** Unassign Practitioner from organization
/** Un-assign Practitioner from organization
* @param {practitionerId} practitioner - the practitioner
* @param {organizationId} org - the organization
* @param {serviceClass} service - the openSRP service
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export const loadOrgPractitioners = async (

/** loads the organization data
* @param {typeof OpenSRPService} service - the opensrp service
* @param {typeof fetchOrganizations} fetchOrganizationsCreator - action creator
* @param {typeof fetchOrganizations} fetchOrganizationsCreator - action creator,
*/
export const loadOrganizations = async (
service: typeof OpenSRPService,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,7 @@ describe('src/containers/pages/OrganizationViews/helpers/servicehooks', () => {
mockClass,
fetchPractitionerRolesMock,
fetchPractitionersMock
).catch(e => {
throw e;
});
).catch(err => err);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to use displayError here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Naah!, this is part of the test, I want the error to actually fail the test.

await flushPromises();

// calls the correct endpoint
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ export type PropsTypes = Props & RouteComponentProps;

const PractitionersListView = (props: PropsTypes) => {
const { practitioners, serviceClass, fetchPractitionersCreator } = props;

// functions/methods

/** function to handle the submit on the inline search form */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { fetchPractitioners, Practitioner } from '../../../../store/ducks/opensr
*/
export const loadPractitioners = async (
service: typeof OpenSRPService = OpenSRPService,
fetchPractitionersCreator: any
fetchPractitionersCreator: typeof fetchPractitioners
) => {
const serve = new service(OPENSRP_PRACTITIONER_ENDPOINT);
serve
Expand Down
23 changes: 16 additions & 7 deletions src/services/opensrp/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,15 @@ export function getFilterParams(obj: URLParams | {}): string {

/** get payload for fetch
* @param {HTTPMethod} method - the HTTP method
* @param {AbortSignal} signal - used to communicate with/abort a DOM request.
* @returns the payload
*/
export function getPayload(method: HTTPMethod) {
export function getPayload(method: HTTPMethod, signal: AbortSignal | null) {
const applySignal = signal ? { signal } : {};
return {
headers: getDefaultHeaders() as HeadersInit,
method,
...applySignal,
};
}

Expand Down Expand Up @@ -89,11 +92,17 @@ export class OpenSRPService {
public baseURL: string;
public endpoint: string;
public generalURL: string;
public signal: AbortSignal | null;

constructor(endpoint: string, baseURL: string = OPENSRP_API_BASE_URL) {
constructor(
endpoint: string,
signal: AbortSignal | null = null,
baseURL: string = OPENSRP_API_BASE_URL
) {
this.endpoint = endpoint;
this.baseURL = baseURL;
this.generalURL = `${this.baseURL}${this.endpoint}`;
this.signal = signal;
}

/** create method
Expand All @@ -107,7 +116,7 @@ export class OpenSRPService {
public async create<T>(data: T, params: paramsType = null, method: HTTPMethod = 'POST') {
const url = getURL(this.generalURL, params);
const payload = {
...getPayload(method),
...getPayload(method, this.signal),
'Cache-Control': 'no-cache',
Pragma: 'no-cache',
body: JSON.stringify(data),
Expand All @@ -132,7 +141,7 @@ export class OpenSRPService {
*/
public async read(id: string | number, params: paramsType = null, method: HTTPMethod = 'GET') {
const url = getURL(`${this.generalURL}/${id}`, params);
const response = await fetch(url, getPayload(method));
const response = await fetch(url, getPayload(method, this.signal));

if (!response.ok) {
throw new Error(
Expand All @@ -154,7 +163,7 @@ export class OpenSRPService {
public async update<T>(data: T, params: paramsType = null, method: HTTPMethod = 'PUT') {
const url = getURL(this.generalURL, params);
const payload = {
...getPayload(method),
...getPayload(method, this.signal),
'Cache-Control': 'no-cache',
Pragma: 'no-cache',
body: JSON.stringify(data),
Expand All @@ -178,7 +187,7 @@ export class OpenSRPService {
*/
public async list(params: paramsType = null, method: HTTPMethod = 'GET') {
const url = getURL(this.generalURL, params);
const response = await fetch(url, getPayload(method));
const response = await fetch(url, getPayload(method, this.signal));

if (!response.ok) {
throw new Error(
Expand All @@ -198,7 +207,7 @@ export class OpenSRPService {
*/
public async delete(params: paramsType = null, method: HTTPMethod = 'DELETE') {
const url = getURL(this.generalURL, params);
const response = await fetch(url, getPayload(method));
const response = await fetch(url, getPayload(method, this.signal));

if (response.ok || response.status === 204 || response.status === 200) {
return {};
Expand Down
Loading