cantierecreativo / redux-bees Goto Github PK
View Code? Open in Web Editor NEWA nice, short and declarative way to interact with JSON APIs
A nice, short and declarative way to interact with JSON APIs
My server isn't responding to redux-bees requests currently, so the request in the network tab of chrome dev tools just says pending forever -- meanwhile, the component renders over and over again -- I eventually get a maximum call stack reached error.
Is there anyway to specify how long to wait for a request to resolve before giving up?
In the example app, the API key is static. What if the API depends on a particular user having his own API key?
In the "Customize headers" section fo the README, I think this example assumes the store is instantiated and has the API key already. But what if you must fetch it first? There's no action to set the API key on Bees.
Does anyone have an example of a non-static API key that would work outside a single file with a self-contained app?
Hi, @stefanoverna !
In the json-api specification, it is possible to create a meta field in a resource object and pass non-standard meta-information there.
http://jsonapi.org/format/#document-top-level
Sometimes this is useful and you need to keep this information in the state of our application.
For my application, this is exactly what I need, but I was faced with the fact that the library does not add meta information anywhere.
I analyzed the code and thought about how and where to add this meta-object.
I think it's best to do this in reducers/entities.js in line number 37, you can just add the code:
if(meta) { newState = immutable.set( newState, 'meta', meta ); }
Currently I want to do something like this:
@query('categories', ingester.getCategories, (perform, {params}) => {
if (!params.categoryId) {
return perform()
}
})
But because query always expects a function to be returned I have to do this:
@query('categories', ingester.getCategories, (perform, {params}) => {
if (!params.categoryId) {
return perform()
}
return () => {}
})
Hi,
Is there an options to add a custom header to a single endpoint only. For example my login expects a POST request with content-type application/x-www-form-urlencoded but all other posts are expecting json
Thanks
esp if the token is stored in local storage.
maybe an auth token needs to be loaded into the store on app boot, and then get that out of the state to trigger a call to users/current-user
?
Hi, looking to use this on a project. Just had a quick question about doing pagination with the query HoC. Would you have any examples of doing that? query wouldn't provide enough on its own to support displaying a component with paging correct? The props it would provide would just be for the requests it performed. I was thinking you would have some kind of UI state in your store that controls the current page, query and perform would hook into that to issue calls and I guess I'd need a custom piece in my mapStateToProps to pull in all the data (existing calls that happened + the new page)?
Or would it be better to not use the HoC in those contexts? Just dispatch the events myself? Wondering how you guys handle pagination in your app that uses this library. Any guidance would be appreciated!
Hi!
I recently started using this library and so far I've been very impressed. I have run into a bit of an issue though that I think either I'm doing something I'm not supposed to, or this is a case where it could be made easier to use.
Per the documentation, if I perform a fetch such as dispatch(api.getPosts({ is_active: true }))
, I can retrieve the results in my mapStateToProps
function by writing getRequestInfo(state, api.getPosts, [{ is_active: true }])
.
That works fine, however, I also want to put the search criteria into my query string so the search persists if the page gets refreshed. After a round trip through the query string, the parameter becomes { is_active: "true" }
and it fails to match the request that's already in the redux store because "true" !== true
. I could transform any non-string query string parameters, but that sounds like a nightmare to have to maintain.
I'd like to see an option to fetch a request using a given name dispatch(api.getPosts({ is_active: true }, { requestId: "search" }))
and then retrieve it using the name instead of the args getRequestInfo(state, api.getPosts, { requestId: "search" })
. Does that sound feasible?
As a hack, I was able to approximate this behavior by adding a toJSON
override to my query object: { is_active: "true", toJSON() { return "search" } }
and it worked, I could retrieve it with getRequestInfo(state, api.getPosts, ["search"])
.
This looks great! The declarative data fetching reminds me of the Preact ecosystem's wiretie, and I've been passively hoping for a React equivalent.
Quick question: if I just want to use the Query HOC as a general purpose declarative fetch using local component state, is that possible without integrating with a Redux store? Wondering if implementation is as coupled to Redux as the name implies ๐
If you use redux-bees in a chunked application, the logic for many other pages can be chunked up into files that can be loaded later with Webpack JSONP but the object for API calls will be full of endpoints that won't be used - making the main chunk file larger.
So you should add the ability to call this function which would generate a new function, for example, API.getDifferentPosts()
dynamically.
API.addEndpoints({
getDifferentPosts: { method: get, path: '/path/to/different/apis' }
});
The docs say to use redux-bees state selectors but for a case when all we want to do is check if an entity exists in state, is there any issue checking in state without a selector?
How do you add arbitrary params to a url?
I would like to redirect to my login page if any request returns 401. How can I do that ? Is there a way to listen to any request result ?
please consider separating out the jsonapi api and the redux integration into individual repos
Nice library, everything works as expected, except for one thing I'm confused about.
Calling invalidateRequests successfully sets invalid=true in my store. However the only place in the redux-bees code where this is checked is in the hasRequestStarted selector.
I would have thought this would cause other selectors to ignore that item in the store, but that doesn't seem to be the case. Invalidating an API call effectively seems to do nothing. What is the intended usage?
I my our setup we want the query HOC to fetch the data, save it in the redux store (which it obviously does), but reuse that data, when its component is mounted for a second time, and avoid that extra http call.
What would be a good way of achieving this?
Hey!
Thanks for bees!
When I receive a 404 or any other error response the console show an uncaught error.
Uncaught (in promise) Object
Everything still works, but I'm wondering why this error appears.
I've reached a number of dead ends implementing redux-bees and I'm struggling to find a way forward due to two core issues. First, let me explain my requirements:
Unfortunately, it seems thus far that there are a number of inherent issues that prevent me from having this. Most notably being that I may need to refresh a token before the API is requested. To avoid this happening more than once for concurrent requests I've implemented redux-saga to solve
@query()
doesn't dispatch any action before the fetch
is madeIf it did I could:
@query
I lose all of the good aspects of redux-bees
If I instead:
GET_AUTHENTICATED_USER
from my componentapi.getAuthenticatedUser()
The request works fine, I get back the data but no further dispatches are made that put the data into the store.
I'm at a little bit of a loss over how to proceed without dropping this library. Perhaps I'm missing something. I'd very much appreciate it if @stefanoverna could provide some further insights into the issues I've been facing.
Besides 'after' middleware(s), a 'before' middleware would probably also be a good idea.
I recently ran into an issue where I had to refresh a token if it was past a certain date.
I ended up wrapping all my api calls & query decorators with a check that would do the refresh, but it'd of course be much better if this could be configured globally from bees itself.
I think it'd look something like this:
before(...args) {
return new Promise(resolve => setTimeout(() => resolve(...args);
},
Hi, I'm using redux-bees for my project to interface with my JsonApi backend.
I'm having problems accessing data that's included with a response from my backend using the getRelationship()
method.
The example included in the readme
covers how to use getRelationship()
and connect()
to retrieve included data with a single object, but the response I'm working with has multiple objects that each map to some included data.
This is the response I get from the backend, I want to access the cities
included with it.
{
"data": [
{
"id": "1",
"type": "countries",
"attributes": {
"title-en": "Kuwait",
"title-ar": "ุงููููุช"
},
"relationships": {
"cities": {
"data": []
}
}
},
{
"id": "2",
"type": "countries",
"attributes": {
"title-en": "Egypt",
"title-ar": "ู
ุตุฑ"
},
"relationships": {
"cities": {
"data": [
{
"id": "7",
"type": "cities"
},
{
"id": "8",
"type": "cities"
}
]
}
}
}
],
"included": [
{
"id": "7",
"type": "cities",
"attributes": {
"slug": "cairo",
"title-en": "Cairo",
"title-ar": "ุงููุงูุฑุฉ"
},
"relationships": {
"areas": {
"data": []
}
}
},
{
"id": "8",
"type": "cities",
"attributes": {
"slug": "alexandria",
"title-en": "Alexandria",
"title-ar": "ุงูุฃุณููุฏุฑูุฉ"
},
"relationships": {
"areas": {
"data": []
}
}
}
]
}
The function getRequestMeta() is not exported in the index.js file
As with baseUrl it would be nice if the headers configuration could also be dynamic. The headers may change as when a user logs in.
I'm now using this library within a TypeScript project. Would it be fine to submit a PR with typings for full TypeScript support?
I have a problem for my routes, I try to call a route with 2 params in it but a got the following message : API call cannot be performed. The following params were not specified: index
Here the declaration of my route
endPoind: { method: destroy, path: '/api/model/:id/subModel/:index' }
And here how I call it
Api.endPoind({ id: 12, index: 0 })
If someone have any idea to resolve it, or if do something bad
Hi, I'm using redux-saga for async actions. And faced with this issue. I'm getting the error (proxyConsole.js:56 The "putJob" API call cannot be performed. The following params were not specified: id) when trying to make a put
request.
But I don't have this error for get
method in exact same code.
api.js
...
putJob: { method: put, path: "/jobs/:id" },
...
putJobSaga.js
...
const newJob = yield call(API.putJob, { id: id });
...
Please check here https://bundlephobia.com/result?p=redux-bees
MissingDependencyError
This package (or this version) uses `redux`, but does not specify them
either as a dependency or a peer dependency
I searched the readme, but didn't find anything on: http://jsonapi.org/format/#fetching-sparse-fieldsets
with include and sparse fieldsets, json:api
has all the same features as graphql sans typing and schema generation.
In a server side rendering set up, you'd preferably not render any components until all of them have their data ready.
Has there been put any thought into this yet?
Specifically in combination with the query
HOC?
Here's how I think it could look:
The query.js
Wrapper
class exposes a static function which accepts a redux dispatch function as first argument. It will return a promise that resolves once data is loaded, and dispatches all data to the passed redux function along the way.
The server (with the help of react-router or something similar) then checks which components match the route path and calls all of the static functions if they're available.
Then, if all of these promises have been resolved, the server side can render the components and finish the request.
Hello)
Is it possible to create a request with like below using redux-bees?
http://localhost:3000/cities?filter[country_id]=1
I had tried
api.getCities({ filter: { country_id: countryId } })
but got only
http://localhost:3000/cities?filter=%5Bobject%20Object%5D
Hey guys great job on the module. I think I found an issue where the library isn't exactly following JSONAPI spec, though possibly I'm interpreting the spec wrong too.
I tried to do a call to an api endpoint like so { method: destroy, path: '/post/:id/relationships/comments' }
with the following payload:
{
data: [
{ type: "comments", id: "1" },
{ type: "comments", id: "2" }
]
}
I expected to see that these relationship records would be deleted though I ended up getting an error from my server as the body of the JSONAPI request was missing.
This is due to http method not adding the body for a DELETE request here in the destroy function, which would normally make sense apart from when you're destroying resources that are part of a 'to-many' relationship.
In the JSONAPI spec in the 'updating to-many relationships' section it says:
A server MUST respond to PATCH, POST, and DELETE requests to a URL from a to-many relationship link as described below. For all request types, the body MUST contain a data member whose value is an empty array or an array of resource identifier objects.
Obviously because the destroy method does not include the body this will not work in redux-bees. I have tried running the query in a curl request to my laravel JSONAPI server with no problem so it seems at least my PHP JSONAPI library has also interpreted the spec the same as what I have.
Hello,
i am trying to get redux-bees work with a cookie authentication.
Until now it works in firefox only. I have found out, that I need to add the parameter credentials:'include' to the call. But adding it to the header parameters does not work, it needs to be outside of the header in the fetch call.
like so:
fetch('https://[ENDPOINT]', {
method: "GET",
...apiConfig,
credentials: 'include'
})
where can I slip this parameter into redux-bees so it will appear at the right position in the fetch call?
Hey there,
I would like to use the HOC of this library but I'm not able to use the decorator syntax due to other project requirements. Is it still possible to use the query
and branch
HOC's without the decorator syntax?
Hey,
I can't find a solution within redux-bees for removing an entity that was successfully removed.
Do I have to implement this feature on my own?
Thank you!
Please create a multi sort
example got http error handling , redux-bees only return body
I'm not really sure how to use this library with React-Redux. I've got things wired up and I can see data in the bees section of the store and request data directly from the API, but how do you use mapStateToProps and mapDispatchToProps here?
Assuming apiEndpoints
includes getBee: { method: get, path: '/bee/:id' }
Ho do you expose the actions and response from the API?
mapDispatchToProps(dispatch) {
return({
beeActions: bindActionCreators(/* something here */, dispatch),
})
}
mapStateToProps(state) {
return({
bee: /* the bee resource (beesource, if you will) */
})
}
And what if you're using include
in the request? I see the getRelationship
function in the React example, but how would you map those to the props? Is there a way to normalize that data passed into the prop? Is that what is supposed to be done?
Hi! I've been following the documentation and tried to pass down some props from an API call through the query
decorator. However, it doesn't pass down the props. What am I missing?
To get an example, I'm using the same syntax as in the state selectors
section, but with another component.
keep up the great work ๐
I'm working with a python backend that I have little control over, and I receive all my server responses in snake_case.
The option for afterResolve
is really helpful in this scenario so I can keep using camelCase in js and persisted state.
However for making requests, I need to provide snake_case again and it's cumbersome to convert on every single api call:
api.updatePost(
{ id: 12 },
snakecaseKeys({ postId: 12, postType: 'post', postAttributes: { ... } } ),
)
It would be great to be able to set a transform on every request via the global config:
const config = {
baseUrl: 'https://api.yourservice.com',
transformBody(body) {
return snakecaseKeys(body);
},
afterResolve({ status, headers, body }) {
return Promise.resolve({ status, headers, body: camelcaseKeys(body) });
},
And optionally override via individual configs too:
api.createWithoutSnakecase(
{ /* placeholders */ },
{ /* body */ },
{
transformBody: (body) => body,
afterResolve: (response) => Promise.resolve(response),
}
)
I can take a stab at a PR if you'd like.
Thanks for the great library!
When you have a list of items already loaded, if one of items was updated, it seems you always have to invalidate and make the request again to the whole list of resources. This is the same for a new resource being added. So a new message comes in for example, and you have to fetch ALL messages. This is how the documentation suggests you do it but it is pretty non-performance. Particular when you want to be able to patch in updates from items within a list. You don't want to be always making the API call for a whole list of things just because one of them updated.
Anyone come up with a solution for this using bees?
Proposal:
For consistency naming with http methods rename destroy
to delete
.
I can make pull request if you wish.
I upgraded redux-bees to the latest version and now cannot compile the project, getting the following error
Failed to minify the code from this file:
./node_modules/redux-bees/lib/selectors.js:57
Read more here: http://bit.ly/2tRViJ9
Hi, great work on this library. Is there any plan to add in offline support?
Say, when requesting data, it can serve the offline / cache version.
Or maybe to allow a callback function to do this.
Thanks in advance.
Is it possible to access the top level response object per API call?
Currently the problem we have is that if we populate a list by making a query and including relationships, if somewhere else on the screen you may make a different call with different requested relationships, the top level entity is updated with the new relationship. So if your original query populated a table, for example, and accessed those relationships, things break down because now one entity in that list no longer has the relationships it originally had.
To simplify lets say you make a call to get posts with comments included. So you end up with
Get all posts with comments
entities
But on the same screen perhaps post 2 gets update via another query with a different requested shape like
Get a single individual post with author
So now your top level entities has:
entities
So the table that was originally populated with posts and something related to comments will break because suddenly comments disappear from one of those top level posts.
the customized header cannot support mode like
configureHeaders(headers) { return { ...headers, mode: 'no-cors' } }
how can i change fetch mode there
Hello, Stefano!
I liked your library for interacting redux and json-api. Great work!
https://github.com/cantierecreativo/redux-bees
But I have a few questions for you, as a developer.
How long will you support this library?
I would like to use your solution on my project, but I want to be sure that I will not see the library through time with status - it is not supported.
How confident can you use this library for prouction?
I mean, is it well tested and will there be any drastic changes to the API in the future?
What browser support does your library have?
I saw that you are using the fetch and promise method to communicate with the server. Maybe there are some other ways to communicate with the server to support older browsers.
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.