Skip to content

Commit

Permalink
additional hook
Browse files Browse the repository at this point in the history
  • Loading branch information
juliancwirko committed Sep 4, 2022
1 parent 1a90ee6 commit 35ded53
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 10 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
### [2.1.0](https://github.com/ElrondDevGuild/nextjs-dapp-template/releases/tag/v2.1.0) (2022-09-04)
- new `useApiCall` hook, check the readme for more info

### [2.0.1](https://github.com/ElrondDevGuild/nextjs-dapp-template/releases/tag/v2.0.1) (2022-08-13)
- fix problems with rerendering (wrong memo usage)
- update dependencies
Expand Down
25 changes: 20 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ It has straightforward and complete functionality.
### Main assumption for the dapp:

- it works on Nextjs
- it uses erdjs 11.\* without the dapp-core library.
- it uses erdjs 11.* without the dapp-core library.
- it uses backed side redirections to hide the API endpoint. The only exposed one is `/api/elrond` and it is used only be the dapp internally
- it uses the .env file - there is an example in the repo (for all configuration, also for the demo config)
- it uses chakra-ui
Expand Down Expand Up @@ -149,17 +149,15 @@ const {
isLoading, // pending state for initial load
isValidating, // pending state for each revalidation of the data, for example using the mutate
error,
} = useScQuery <
number >
{
} = useScQuery<number>({
type: SCQueryType.NUMBER, // can be number, string or boolean
payload: {
scAddress: process.env.NEXT_PUBLIC_MINT_SMART_CONTRACT_ADDRESS,
funcName: process.env.NEXT_PUBLIC_QUERY_FUNCTION_NAME,
args: [],
},
autoInit: false, // you can enable or disable the trigger of the query on the component mount
};
});
```

#### useLoggingIn()
Expand All @@ -186,6 +184,23 @@ The hook will provide the information about the user's auth data state. The data
const { loginMethod, expires, loginToken, signature } = useLoginInfo();
```

#### useApiCall()

The hook provides a convenient way of doing custom API calls unrelated to transactions or smart contract queries. By default it will use Elrond API endpoint. But it can be any type of API, not only Elrond API. In that case you would need to pass the `{ baseEndpoint: "https://some-api.com" }` in options

```jsx
const { data, isLoading, isValidating, fetch, error } = useApiCall<Token[]>({
url: `/accounts/<some_erd_address_here>/tokens`, // can be any API endpoint without the host, because it is already handled internally
autoInit: true, // similar to useScQuery
type: 'get', // can be get, post, delete, put
payload: {},
options: {}
});
```

You can pass the response type. Returned object is the same as in `useScQuery`
The hook uses `swr` and native `fetch` under the hood.

### Working with the API

The API endpoint is proxied on the backend side. The only public API endpoint is `/api/elrond`. This is useful when you don't want to show the API endpoint because, for example, you use the paid ones. Also, there is an option to block the `/api/elrond` endpoint to be used only within the Dapp, even previewing it in the browser won't be possible.
Expand Down
67 changes: 67 additions & 0 deletions hooks/core/useApiCall.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import useSWR from 'swr';
import useSwrMutation from 'swr/mutation';
import { apiCall } from '../../utils/apiCall';

interface ApiCallData {
url: string;
type?: string;
payload?: Record<string, unknown>;
options?: Record<string, unknown>;
autoInit?: boolean;
}

interface FetcherArgs {
url: string;
type?: string;
payload: Record<string, unknown> | undefined;
}

export async function fetcher({ url, type, payload }: FetcherArgs) {
if (type === 'post') {
return await apiCall.post(url, payload || {});
}
if (type === 'put') {
return await apiCall.put(url, payload || {});
}
if (type === 'delete') {
return await apiCall.delete(url);
}
return await apiCall.get(url);
}

export function useApiCall<T>({
url,
type,
payload,
options,
autoInit = true,
}: ApiCallData) {
const { data, error, mutate, isValidating, isLoading } = useSWR(
autoInit ? { url, payload, type } : null,
fetcher,
{
revalidateIfStale: true,
revalidateOnFocus: false,
revalidateOnReconnect: true,
...options,
}
);

const {
data: mutationData,
error: mutationError,
trigger,
isMutating,
} = useSwrMutation({ url, payload, type }, fetcher, {
populateCache: true,
revalidate: true,
});

return {
data: (data || mutationData) as T,
isLoading: isLoading,
isValidating: isValidating || isMutating,
error: error || mutationError,
fetch: autoInit ? mutate : trigger,
};
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "nextjs-dapp-template",
"version": "2.0.1",
"version": "2.1.0",
"author": "Julian Ćwirko <julian.io>",
"license": "MIT",
"homepage": "https://github.com/ElrondDevGuild/nextjs-dapp-template",
Expand Down
8 changes: 4 additions & 4 deletions utils/apiCall.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const apiCall = {
};

const response = await fetch(
this.baseEndpoint + endpoint,
(options?.baseEndpoint || this.baseEndpoint) + endpoint,
Object.assign(defaultOptions, options || {})
);

Expand Down Expand Up @@ -45,7 +45,7 @@ export const apiCall = {
};

const response = await fetch(
this.baseEndpoint + endpoint,
(options?.baseEndpoint || this.baseEndpoint) + endpoint,
Object.assign(defaultOptions, options || {})
);

Expand Down Expand Up @@ -75,7 +75,7 @@ export const apiCall = {
};

const response = await fetch(
this.baseEndpoint + endpoint,
(options?.baseEndpoint || this.baseEndpoint) + endpoint,
Object.assign(defaultOptions, options || {})
);

Expand All @@ -100,7 +100,7 @@ export const apiCall = {
};

const response = await fetch(
this.baseEndpoint + endpoint,
(options?.baseEndpoint || this.baseEndpoint) + endpoint,
Object.assign(defaultOptions, options || {})
);

Expand Down

0 comments on commit 35ded53

Please sign in to comment.