marcin-piela / react-fetching-library Goto Github PK
View Code? Open in Web Editor NEWSimple and powerful API client for react ๐ Use hooks or FACCs to fetch data in easy way. No dependencies! Just react under the hood.
License: MIT License
Simple and powerful API client for react ๐ Use hooks or FACCs to fetch data in easy way. No dependencies! Just react under the hood.
License: MIT License
Hello, I'd like to ask you, what you think about to expose in client
the stream body response
Hello
I am using react-testing-library to test my network components and it was working fine until 1.5.6 version. After upgrading to 1.5.7 I am observing failures
Sample testcase:
it('fetches resource and returns proper data on success', async () => {
const id = '12345';
const type = 'text';
const fetchFunction: () => Promise<QueryResponse> = async () => ({
error: false,
status: 200,
payload: successResponse,
});
const Client = createClient({
params: { host: 'https://mockHost', basePath: 'mockPath', defaultQueryParams: {} },
});
Client.query = fetchFunction;
const wrapper = ({ children }: any): any => (
<ClientContextProvider client={Client}>{children}</ClientContextProvider>
);
jest.useFakeTimers();
const { result } = renderHook<void, any>(
() => useFetchQuery(id, type),
{
wrapper: wrapper,
},
);
expect(result.current.loading).toEqual(true);
expect(result.current.error).toEqual(false);
act(() => {
jest.runAllTimers();
});
expect(result.current.loading).toEqual(false);
expect(result.current.error).toEqual(false);
});
Issue: Looks like there is some issue with the request interceptor. There is null response from interceptor
I am stuck with 1.5.6 release but i have to upgrade it to latest version to use some of its features
Both useMutation
and useBulkMutation
may end up using cached query responses if the action doesn't change between mutations (e.g., the POST data remains the same). It seems wrong to me that mutations would be cached.
The query
function has a skipCache
flag that needs to be set on these two lines:
I'll submit a PR for this after I free up some time.
When using useBulkMutation
with a large number of elements, it triggers a lots of request (expected).
I was thinking to include a way to be able to batch the requests and got some ideas:
useBulkMutation
mutate
of useBulkMutation
to specify a function wrapper for the query
call (see POC).client.query
call to allow for global batching or action-batchingNot really sure if any of these sound OK to you.
Add useCache hook to get cached response by Action
object.
Currently, when adding this dependency to a Create React App project, the tests will start to fail. This is due to the published code using es syntax like import/export.
It is quite common to either just publish cjs-code, or perhaps put the es code in their own "es" folder for people who want to transpile it themselves. The first good example I can think of is https://github.com/FezVrasta/react-popper which I think has quite good code.
In the meantime, a workaround for people using Create React App or a configuration like it is to add --transformIgnorePatterns "node_modules/(?!(react-fetching-library)/)"
to the jest-command.
Change naming from HOC to FaCC (Function as Child Component) in documentation.
Hey @marcin-piela, first of all I want to say that this is a really cool library. Unfortunately we had a problem using our Bearer token in each request. As described in the documentation we have implemented the token in a RequestInterceptor. Unfortunately your library only takes the token with which the client was initialized. Unfortunately the client does not update itself when the token changes. Would you have a suggestion or an example of how we could implement this? We would be very happy because we would like to use the package productively.
Provide useBulkMutate hook to allow define multiple actions, e.g. if calling a bulk edits or deletes on a single hook.
const {mutate} = useMultipleMutate(createAction);
const handleSubmit = (values) => {
const response = await mutate(values); // values is (e.g.) an array of ids
}
In order to use this library with server-side rendering techniques other than Nextjs, it needs a way to expose all the promises registered via useQuery
so the server-side can await all those promises to resolve before re-rendering the application.
Not sure if doing something wrong or a bug.
My use case is that I want to create an interceptor depending on state, lets say that I want to append a header X-COUNT
to my requests (or a user token) on every request, but the count changes over time (I don't know the user token beforehand, the user needs to login).
What I tried is to create the client when this particular variable changes, and using it with the interceptor.
https://codesandbox.io/s/react-fetching-library-ssr-nextjs-5zisb
The problem I'm seeing is that even the client builder is being called, the queries still use the very first values.
Is there a way to update the interceptors?
Im running code similar to this:
doQuery({
method: 'POST',
endpoint: '/v1/bil/drivmedelspris/prislinjen',
body: prislinjenRapport
}).then((value) => {
console.log(value)
})
This is a CORS request, so I can see that a OPTION and POST takes place, both returning 204 no content. The response that is logged is of this type:
{"error":true,"errorObject":{ SyntaxError: Unexpected end of JSON input at... }}
As I see it, there is two problems here. Both that the error occurs, and that I receive insufficient information in the error that is thrown. I cant see the status code of the request or anything like that.
This simple line in cache.ts will make webpack bundle an extra 19 kb shim for client-side scripts:
export const convertActionToBase64 = (action: Action) => {
return Buffer.from(JSON.stringify(action)).toString('base64');
};
Would it not be better to use a simple string concat like this:
const convertActionToBase64 = (action) => {
return `${action.method}${action.endpoint}`
}
Add example of integration with REDUX (using request/response interceptors)
Right now Client
instance doesn't expose CacheProvider
, it should be possible to access it directly from Client
instance.
Just a quick question regarding the hooks useMutation
and useQuery
.
What is the main difference between the two? If I set the initFetch
param of useQuery
to false
the hooks seems to behave very similar to what useMutation
is doing. Am I correct on that?
API of React Suspense will change in future, so in documentation info about it should be added.
Hello,
There is a problem to find basic types during SSR request in nextjs getServerSideProps.
It appears that Node has some problems to validate basic types, FormData and Blob.
Request tried:
export const listFromCategory = ({ categorySlug, limit = 24, page = 1 }: { categorySlug: string, limit?: number, page?: number }): Action => ({
method: 'POST',
endpoint: `/products/list/limit/${limit}/page/${page}`,
body: {
domain: {
type: 'category',
value: categorySlug,
},
},
credentials: 'omit',
});
Is there something that I'm doing wrongly?
Thank you in advance.
Hi,
I have been using this library for data fetching in a Suspense-enabled React application I am building. However, it occurred to me that useSuspenseQuery
does not use the cacheProvider
given to the client, but instead uses a global cache.
Is there any reason why useSuspenseQuery
uses a global cache instead of the cache from the client? In my case, I cannot share caches/clients between requests as to prevent sensitive information from leaking between requests.
After calling mutate, I need to reinit if there's some error. Is it currently possible? I don't find a method that satisfies that condition
Thanks for this amazing library. It looks great and almost works perfectly!
I'm trying to set this up in a SSR NextJS project. I've used these instructions from the documentation and SSR works great.
My next step was to add a requestInterceptor so that I don't have to type the base API domain over and over again. For this I used your example host interceptor. As follows:
const requestHostInterceptor = host => client => async action => {
return {
...action,
endpoint: `${host}${action.endpoint}`,
}
}
export const client = createClient({
cacheProvider: cache,
requestInterceptors: [requestHostInterceptor('http://local.api.dev')],
})
But SSR stops working as soon as I add the requestInterceptors
property to createClient
. The endpoint gets called twice (first backend, then frontend again because it finds there is no cache). So the client is making the call correctly from the backend to the api, but somehow the payload remains undefined
while rendering on the server.
I've looked through the code, but can't find any pointers. Do you have any ideas?
It would be great if createClient able to accept the other client fetch like axios
.
I will make pull request when I have time
I'm updating from 1.5 to 1.7 and have a function that returns an object of type UseMutationResponse
. However this type doesn't seem to be exported by the library, i.e. TS2459: Module '"../../../node_modules/react-fetching-library/lib"' declares 'UseMutationResponse' locally, but it is not exported.
Is this an oversight? Since UseQueryResponse
actually is exported and usable within a project.
Thanks for the great library!
What is the way to handle fetchMore? I see the query
function returned from useQuery
hook .but it doesn't seem to take any parameters.
When fetching content with the <Query/>
component and an error occurs, no status is passed. It is always undefined.
Prepare interceptors for :
I need to refresh view after adding new data. I know that "useQuery" hook has that ability by calling "query" function, however I would like to have similar result with "useSuspenseQuery". It is also possible by changing action, which is used as cache key, but I need to call it again with same action as before. Is it possible somehow to clean that cache or any other way of using "useSuspenseQuery" hook multiple times from same component without changing action ?
Allow to configure error boundaries in ClientProvider, add ie. resolve function to decide when throw error (for example only 500 status).
Looking at the code, the library currently will parse the responses to either text
or json
. However for our application we need to also support binary data (such as images and PDF's).
Am I correct that a binary response (ArrayBuffer
or Blob
) currently is not supported? If so I would like to implemented such a feature and create a PR for it.
@marcin-piela would you have any thoughts on the implementation? Maybe we can add a responseType
property as part of the Action
interface...?
Is there any method from cache
to return cache data to client ?
Right now we have to run linter and formatted manually.
I Am Trying To Get Access Token From Redux State Like This.
I Don`t Know What I Am Doing Wrong But When The Access Code Changes It Doesn't Change In The Request Inceptor. That Is The Old Access Code Is Still Used After Access Code Has Change In Redux State
const { store } = configureStore();
const apiTokenInterceptor = host => client => async action => {
const state = store.getState();
const { auth } = state;
return {
...action,
endpoint: getUrl(action.endpoint),
headers: {
...action.headers,
"Content-type": "application/json",
Accept: "application/json",
Authorization:` Bearer ${auth.token}`
}
};
};
Hi, sorry for the newbie question but I'm having a hard time getting this library to make a get request without first sending an options request.
I'm simply trying to fetch my treehouse points from this endpoint:
https://teamtreehouse.com/jonathanwalz.json
Using the fetch api, it works perfectly:
fetch('https://teamtreehouse.com/jonathanwalz.json')
Is there anyway to make a get without options? Thanks in advance.
Hello.
I'm using useParameterizedQuery()
function and I have an action with URL params set like this:
export function fetchFlyby(
holeIndex: number,
clubShortName: string,
): Action<ApiSchemas.IFlyby> {
return {
method: 'GET',
endpoint: `${API_URL}/flyby?s={"$and":[{"club.shortName": "${clubShortName}"}, {"holeIndex": "${holeIndex}"}]}`,
};
}
When I print my action before query call I'm getting this string http://localhost:5000/v1/flyby?s={"$and":[{"club.shortName": "test"}, {"holeIndex": "1"}]}
. So until now it looks fine.
But something wrong is happening while endpoint transformation when my api server (nest.js) recieves following url route /v1/flyby?s=%7B%22$and%22:[%7B%22club.shortName%22:%20%22undefined%22%7D,%20%7B%22holeIndex%22:%20%22[object%20Object]%22%7D]%7D
Have anyone encountered some similar issue? What can I do to prevent from these [objects] that I get on backend?
Thanks!
Am I Right To Assume This Will Not Work On React Native?.
Documentation says React Dom is a requirement
When I try to reexecute useSuspenseQuery
query and have cacheProvider set, no network request occurs. It always gets new data from cache, instead of making a new request.
Provide useMutate hook to allow define actions without using client.query
directly,
ie
const {mutate} = useMutate(createAction);
const handleSubmit = (values) => {
const response = await mutate(values);
}
Create CodeSandbox application with:
Create hooks similar to relay https://relay.dev/docs/en/experimental/api-reference#usepreloadedquery
i think query
from useQuery(action)
would be useful if we pass another params when call the query
function, such as query({page: 2})
;
how do you think? @marcin-piela
Hello!
I got following code:
function loginFetchAction(
email: string,
password: string,
): Action<User> {
return {
method: "POST",
endpoint: "http://localhost:5000/auth/login",
body: { email, password }
};
}
export const AuthContextProvider = ({ children }: Props) => {
const {
loading,
payload,
query,
error,
reset,
abort
// below is error
} = useParameterizedQuery(loginFetchAction);
I can't find out how to properly type this hook. Can anyone help me please? Thanks!
Hello.
I keep getting following errors from TypeScript compilation (using react-fetchiung-library on React Native):
node_modules/react-fetching-library/lib/index.d.ts:15:19 - error TS2304: Cannot find name 'RequestCredentials'.
15 credentials?: RequestCredentials;
~~~~~~~~~~~~~~~~~~
node_modules/react-fetching-library/lib/index.d.ts:16:13 - error TS2304: Cannot find name 'RequestCache'.
16 cache?: RequestCache;
~~~~~~~~~~~~
node_modules/react-fetching-library/lib/index.d.ts:17:12 - error TS2304: Cannot find name 'RequestMode'.
17 mode?: RequestMode;
~~~~~~~~~~~
node_modules/react-fetching-library/lib/index.d.ts:18:22 - error TS2304: Cannot find name 'ReferrerPolicy'.
18 referrerPolicy?: ReferrerPolicy;
~~~~~~~~~~~~~~
node_modules/react-fetching-library/lib/index.d.ts:22:16 - error TS2304: Cannot find name 'RequestRedirect'.
22 redirect?: RequestRedirect;
~
Is there any types package that I need to install in order to get these typings on React Native?
I've tried @types/node
, @types/request
and @types/node-fetch
but without any success.
Thank you so much!
Hello.
I'm using this lib in my React Native project and I need to delay fetch request until certain condition happen (button press, etc.)
For purpose of GET request I'm using useQuery
defined like the one below:
const {payload, error, loading, query} = useQuery<VideoType[]>(action, false);
The problem is that query si fired even when initFetch
param is set to false. Do you have any suggestion please? Am I doing something wrong here?
Thanks!
responseType
param in ActionAdd logger mechanism for development purposes.
useQuery hook keeps returning response from stored cache even when I set cache:"no-cache" in the Action
I use RN states to refresh I my app, it makes a call and returns the cachedResponse and not fresh data. It works fine when I kill and launch my app but does not help while refreshing
Right now only query
method is available in ClientContext
, it should also expose CacheProvider
to ie. easily update cache values from components.
APIARY has limitations and it will be better to user real working API, ie. hacker news?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.