A drop in replacement for apollo client's `useQuery` hook with a return type that mimics Elm's RemoteData ADT
npm install use-query-rduse-query-rd > A drop in replacement for apollo client's useQuery hook with a return type that mimics Elm's RemoteData ADT
- use-query-rd
- Motivation
- Inspo
- useQueryRd
- Pattern Matching
- match
- Signature
- Example
- fold
- Signature
- Example
- Mapping
- map
- Signature
- Example
- andMap
- Signature
- map2
- Signature
- Example
- Constructors
- initialized
- Signature
- pending
- Signature
- failure
- Signature
- success
- Signature
- Refinements
- isInitialized
- Signature
- isLoading
- Signature
- isFailure
- Signature
- isSuccess
- Signature
Tagging network bound data with the state of the request makes _impossible states impossible_. This is highly desirable as data requests and the subsequent handling of fetched data is a common cause of logic and runtime errors in apps.
- RemoteData for Elm
- Make Impossible States Impossible
This is a @apollo/client specific implementation of RemoteData. useQueryRd is a wrapper around useQuery that returns one additional property, _rd. _rd is a RemoteData that is generic across Success. Failure is not generic as it will always be ApolloError.
> useQuery
``typescript`
function useQuery
query: DocumentNode | TypedDocumentNode
options?: QueryHookOptions
): QueryResult
> useQueryRd
`typescript`
const useQueryRd:
query: DocumentNode | TypedDocumentNode
options?: QueryHookOptions
) => QueryResult
_rd: RemoteData
};
Takes a matcher and a RemoteData value. The matcher attributes the RemoteData value to a case and applies the matched function. match support partial matching by supplying a default tag of _. Any RemoteData states no supplied subsequent to the _ will fallback to the function supplied at _. A common use case for this is combining the functions for Initialized and Pending into one "loading" case.
#### Signature
`typescript`
const match:
#### Example
`typescript
import React from "react";
import { useQueryRd, match } from "use-query-rd";
const ContainerComponent = (): JSX.Element =>
match(useQueryRd<{ data: MyDataType[] }>(GET_DATA_QUERY)._rd, {
_:
Failure: (error) =>
Success: (data: MyDataType) =>
});
export default ContainerComponent;
`
Takes four functions corresponding to the four tags and a RemoteData value. The function corresponding to the tag of the value is applied.
#### Signature
`typescript`
const fold:
initialized: () => T,
pending: () => T,
failure: (error: ApolloError) => T,
success: (data: D) => T
) => (_: RemoteData
#### Example
`typescript
import React from "react";
import { useQueryRd, fold } from "use-query-rd";
const ContainerComponent = (): JSX.Element =>
fold(
() =>
() =>
(error) =>
(data: MyDataType) =>
)(useQueryRd<{ data: MyDataType[] }>(GET_DATA_QUERY)._rd);
export default ContainerComponent;
`
Apply the supplied function to the RemoteData if tag is Success, otherwise return original RemoteData
#### Signature
`typescript`
const map:
#### Example
`typescript
const myInitialData = useSomeData()._rd;
const formattedData = map((res: MyResultType) => {
const manipulatedData = doSomething(res);
return {
myManipulatedData: manipulatedData,
};
}, myInitialData);
`
Put the results of two RemoteData calls together. Used to make mapX.
#### Signature
`typescript`
const andMap:
rd1: RemoteData
rd2: RemoteData<(d: RD1) => RD2>
) => RemoteData
Combine two remote data sources with the given function. The result will succeed when (and if) both sources succeed.
#### Signature
`typescript`
const map2:
f: (d: D) => (d2: D2) => D3,
rd1: RemoteData
rd2: RemoteData
) => RemoteData
#### Example
`typescript
export const Map2Example = () => {
const RD1 = useQueryRd<{ launchesPast: Launch[] }>(ROCKETS_QUERY, {
variables: { limit: 100 },
})._rd;
const RD2 = useQueryRd<{ launchpads: Launchpad[] }>(LAUNCHPADS_QUERY)._rd;
const comb =
(rd1: { launchesPast: Launch[] }) => (rd2: { launchpads: Launchpad[] }) => {
return {
one: rd1,
two: rd2,
};
};
return match(map2(comb, RD1, RD2), {
_: () =>
Loading...
,Error while fetching data ({error.message})
,map2
Constructors
$3
Constructs a new
RemoteData with a tag of Initialized. This represents a network request yet to be made.#### Signature
`typescript
const initialized: () => RemoteData;
`$3
Constructs a new
RemoteData with a tag of Pending. This represents an in flight network request.#### Signature
`typescript
const pending: () => RemoteData;
`$3
Constructs a new
RemoteData with a tag of Failure and an ApolloError. While Failure is usually generic in _RemoteData_, useQuery from @apollo/client represents all network failures as ApolloError. Thus, Failure is strictly typed for ApolloError.#### Signature
`typescript
const failure: (error: ApolloError) => RemoteData;
`$3
Constructs a new
RemoteData with a tag of Success. This represents a resolved network requests with a valid response.#### Signature
`typescript
const success: (data: D) => RemoteData;
`Refinements
$3
Returns
true if the rd is an instance of Initialized, false otherwise#### Signature
`typescript
const isInitialized: (rd: RemoteData) => rd is Pending;
`$3
Returns
true if the rd is an instance of Pending, false otherwise#### Signature
`typescript
const isLoading: (rd: RemoteData) => rd is Pending;
`$3
Returns
true if the rd is an instance of Failure, false otherwise#### Signature
`typescript
const isFailure: (rd: RemoteData) => rd is Failure;
`$3
Returns
true if the rd is an instance of Success, false otherwise#### Signature
`typescript
const isSuccess: (rd: RemoteData) => rd is Success;
``