Skip to content

Commit

Permalink
refactor(hooks): Pulling out useData (#7325)
Browse files Browse the repository at this point in the history
  • Loading branch information
alanmquach authored and christopherthielen committed Aug 14, 2019
1 parent 0fbafe6 commit 598b5b3
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import * as React from 'react';
import { IPromise } from 'angular';
import { FormikProps } from 'formik';
import { $q } from 'ngimport';
import { Option } from 'react-select';

import { BuildServiceType, IgorService } from 'core/ci';
import { IConcourseTrigger } from 'core/domain';
import { FormikFormField, ReactSelectInput, useLatestPromise } from 'core/presentation';
import { FormikFormField, ReactSelectInput, useData } from 'core/presentation';

import { ConcourseService } from './concourse.service';

Expand Down Expand Up @@ -36,22 +34,15 @@ export function ConcourseTrigger({ formik, trigger }: IConcourseTriggerConfigPro
formik.setFieldValue('jobName', jobName);
};

// Fetches data when anything in the dependencies list changes
// Returns an empty array if any dependencies are falsey
function useData<T>(callback: () => IPromise<T>, deps: any[]) {
const anyDepsMissing = deps.some(dep => !dep);
const defaultValueCallback = () => $q.resolve(([] as any) as T);
return useLatestPromise(anyDepsMissing ? defaultValueCallback : callback, deps);
}

const fetchMasters = useData(() => IgorService.listMasters(BuildServiceType.Concourse), []);
const fetchTeams = useData(() => ConcourseService.listTeamsForMaster(master), [master]);
const fetchPipelines = useData(() => ConcourseService.listPipelinesForTeam(master, team), [master, team]);
const fetchMasters = useData(() => IgorService.listMasters(BuildServiceType.Concourse), [], []);
const fetchTeams = useData(() => ConcourseService.listTeamsForMaster(master), [], [master]);
const fetchPipelines = useData(() => ConcourseService.listPipelinesForTeam(master, team), [], [master, team]);
const fetchJobs = useData(
() =>
ConcourseService.listJobsForPipeline(master, team, pipeline).then(jobs =>
jobs.map(job => `${team}/${pipeline}/${job}`),
),
[],
[master, team, pipeline],
);

Expand Down
1 change: 1 addition & 0 deletions app/scripts/modules/core/src/presentation/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './useLatestPromise';
export * from './useData';
23 changes: 23 additions & 0 deletions app/scripts/modules/core/src/presentation/hooks/useData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { IPromise } from 'angular';
import { $q } from 'ngimport';
import { isNil } from 'lodash';

import { useLatestPromise, IUseLatestPromiseResult } from './useLatestPromise';

/**
* A react hook which invokes a promise returning callback whenever any of its dependencies changes.
* Returns the provided default value whenever any dependency is null or undefined
*
* This can be useful when fetching data based on a users keyboard input, for example.
* This behavior is similar to RxJS switchMap.
*
* @param callback the callback to be invoked whenever dependencies change
* @param defaultValue the default value to return when any dependencies are null or undefined
* @param deps array of dependencies, which (when changed) cause the callback to be invoked again
* @returns an object with the result and current status of the promise
*/
export function useData<T>(callback: () => IPromise<T>, defaultValue: T, deps: any[]): IUseLatestPromiseResult<T> {
const anyDepsMissing = deps.some(dep => isNil(dep));
const defaultValueCallback = () => $q.resolve(defaultValue);
return useLatestPromise(anyDepsMissing ? defaultValueCallback : callback, deps);
}

0 comments on commit 598b5b3

Please sign in to comment.