Socket
Socket
Sign inDemoInstall

async-selector

Package Overview
Dependencies
Maintainers
1
Versions
24
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

async-selector - npm Package Compare versions

Comparing version 1.0.10 to 1.0.11

23

__tests__/index.test.js

@@ -792,1 +792,24 @@ import createAsyncSelector from '../src/index';

});
test('throttled and forced', done => {
let state = {employees: ['Mark Metzger'], maxAge: 1};
let result = null
const throttle = f => _.debounce(f, 150);
const onCancel = (r, n, a) => {result=[r,n,a]}
const ages = createAsyncSelector(
{...params2, throttle, onCancel},
s => s.employees,
s => s.maxAge);
ages(state);
ages.forceUpdate(state);
ages.forceUpdate(state);
setTimeout(() => {
try {
expect(deepEqual(result, null)).toBe(true);
} catch (e) {
done.fail(e)
}
done();
}, 200);
});

2

package.json
{
"name": "async-selector",
"version": "1.0.10",
"version": "1.0.11",
"description": "Select values from databases using asynchronous selectors.",

@@ -5,0 +5,0 @@ "main": "./dist/index.js",

A simple, lightweight library inspired by [reselect](https://github.com/reduxjs/reselect) which allows you select data out of a remote database almost as easily as you would from local state. This library will normally be used in conjunction with redux and reselect but it has no dependencies.
# Installation
```
npm install --save async-selector
```
# What It solves
A normal (naive) approach to handling fetching data from a database in redux would be
- Initiate a request is response to some event (app loaded, component mounted, search text changed, etc)
- dispatch an action to change a variable in state so you can render a loading message
- handle a promise rejection in a similar way
- handle a promise resolution by populating state with the new data
A normal (naive) approach to handling fetching data from a database in redux would be:
- Initiate a request in response to some event (app loaded, component mounted, search text changed, etc).
- dispatch an action to change a variable in state so you can render a loading message.
- handle a promise rejection in a similar way.
- handle a promise resolution by populating state with the new data.

@@ -13,7 +18,7 @@ ### Problems

- An old request could potential overwrite the data of a newer request if you don't handle that edge case.
- During the time between the request being sent and the response received, you might be rendering stale data.
- Having many variables in state and associated actions/reducers for the query status is a lot of redundant, tedious code.
- If you have requests that depend on previous responses, this could result in callback hell and/or difficulty in reuse of the first response's data.
- During the time between the request being sent and the response received, you might be rendering stale data. In some cases, this can be a dangerous bug.
- Having many state variables/actions/reducers/etc for every query is a lot of redundant, tedious code.
- If you have requests that depend on previous responses, this could result in callback hell and/or difficulty in future reuse of the first response's data.
- There is no guarantee that multiple duplicate requests won't be made.
- Sending queries in response to user actions can result in brittle code and isn't really in the spirit of redux/reselect (Unless it's actually necessary). For example, if you call a function in a server based on many user inputs, you will have to write code to send a query for every input field.
- Sending queries in response to user actions can result in brittle code and isn't really in the spirit of redux/reselect. For example, if you call a function in a server that uses many user inputs, you will have to write code to send a query for every input field. This scales poorly with the complexity of your application.

@@ -90,3 +95,3 @@ # Async selectors to the rescue!

### Usage in redux
A serious problem with the above code is that when the promise resolves, the app doesn't re-render to show the new data. Instead of simply logging the employees in the onResolve callback, we need to dispatch an action to tell the app to re-render and call the selector. This is a bit of a hack because nothing in the state was changed. One thing to make sure of is that the action changes state in some way or a re-render event won't be triggered. Another thing to be careful to avoid is recursion resulting from the action causing the inputs of the selector to change.
A serious problem with the above code is that when the promise resolves, the app doesn't re-render to show the new data. Instead of simply logging the employees in the onResolve callback, we need to dispatch an action to tell the app to re-render and call the selector and get the new value. This is a bit of a hack because nothing in the state was changed. One thing to make sure of is that the action changes state in some way or a re-render event won't be triggered. Another thing to be careful to avoid is recursion resulting from the action causing the inputs of the selector to change.

@@ -124,2 +129,3 @@ ```js

const employeeAges = createAsyncSelector(params2, [employees]);
console.log('Ages:', employeeAges(store.getState()))
```

@@ -132,7 +138,7 @@

function buttonClicked() {
employeeAges(store.getState(), true) // "true" indicates that the selector should create a new promise regardless of whether the inputs changed
const result = employeeAges.forceUpdate(store.getState()) // the selector will create a new promise regardless of whether the inputs changed. It will always return an object in the "isWaiting" state.
}
```
By passing true as the second parameter of the selector, the selector will be called as if the inputs changed thus automatically creating a new promise.
The selector will be called as if the inputs changed thus automatically creating a new promise. With this technique, an async selector could simply be treated like a memoized function and state variable combo.

@@ -161,2 +167,5 @@ ### Throttling queries

### Usage across multiple instances of a component
Just like in reselect, an async selector can take in two variables (for example, global state and component props). Reselect has examples of this [here](https://github.com/reduxjs/reselect#selectorstodoselectorsjs-1).
# Documentation

@@ -179,5 +188,6 @@ createAsyncSelector takes in two arguments:

## selectors
Each selector is a function that takes in state as its argument just like in reselect. It memoizes its results so the only way for it to return a different value for the same inputs is if it contained a promise that was resolved. An async selector is only different from a normal selector in that you can pass in "forceUpdate" bool as the second parameter to force a promise to be made.
Each selector is a function that takes in state (and optionally a second variable) as its argument just like in reselect. It memoizes its results so the only way for it to return a different value for the same inputs is if it contained a promise that was resolved. An async selector is only different from a normal selector in that you can call ".forceUpdate(state)" of state which will automatically create a new promise and return an object in the "isWaiting" state.
```js
function selector(state, forceUpdate=false) -> any
function selector(state, ?props) -> object
selector.forceUpdate(state, ?props) -> object
```

@@ -184,0 +194,0 @@ ## params

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc