-
-
Notifications
You must be signed in to change notification settings - Fork 419
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
loading plugin counts the number of outstanding effects per effect, module, and global #245
Conversation
package.json
Outdated
@@ -39,7 +39,8 @@ | |||
"test": "jest" | |||
}, | |||
"dependencies": { | |||
"redux": "^3.7.2" | |||
"redux": "^3.7.2", | |||
"redux-persist": "^5.9.1" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was a strange thing, but some tests were failing without it...... dunno how it was working before?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I noticed that in your PR. Tests "should" pass with 'redux-persist' as a dev dependency.
}, | ||
effects: { | ||
async timeout() { | ||
await delay(200) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a more standard async
delay call
plugins/loading/test/loading.test.js
Outdated
dispatch.count.timeout() | ||
expect(store.getState().loading.global).toBe(true) | ||
expect(store.getState().loading.global).toBe(2) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is the gist of the new functionality
plugins/loading/test/loading.test.js
Outdated
|
||
dispatch.count.timeout() | ||
dispatch.count.timeout() | ||
expect(store.getState().loading.effects.count.timeout).toBe(2) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is the gist of the new functionality
plugins/loading/test/loading.test.js
Outdated
dispatch.count.timeout2() | ||
expect(store.getState().loading.effects.count.timeout1).toBe(1) | ||
expect(store.getState().loading.effects.count.timeout2).toBe(1) | ||
expect(store.getState().loading.global).toBe(2) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
making sure global increments for every dispatched effect
await origEffect(...props) | ||
// waits for dispatch function to finish before calling "hide" | ||
} finally { | ||
dispatch.loading.hide({ name, action }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
omit catch
, but decrements counter even on an error
Note that the loading plugin will likely require some changes once #236 is merged. Working on this at the moment. At that point, loading can be handled with 2 actions, rather than the current 3.
|
@crazy4groovy - interesting idea - an integer count is certainly more useful than a boolean. I would use this, for its debugging value alone. The only issue I can see is that users with typechecking (TypeScript, Flow) may find it annoying. Do you think it's possible to make it an "opt in" feature? |
@ShMcK interesting point about typechecking. Honestly I'm not strong on the topic so I don't have any insight, sorry. But I didn't see any Boolean -> number is a breaking change, so opt-in would help maintain backwards-compatibility. That is often a smart move, unless the added feature completely trumps the existing functionality. Can you see any case where the new functionality is not better than current? Alternatively a v1.x (semver) bump may be the right move. Thoughts? |
Nope. You have a good idea.
In JS, there is no issue with dynamically typing variables. var loading = 0
if (loading) {
// do something
} But when using TypeScript, for example, the compiler expects variables to be statically typed. var loading = 0
if (loading) { // warning, expected a boolean
// do something
} Then you have to do some nasty coercion to make the compiler happy. var loading = 0
if (!!loading) {
// do something
} I believe these two solutions can co-exist very simply.
What do you think? |
I see. Yes, in JS world (or TS?) I would just expect to check loading like this: var loading = 0
if (loading > 0) { // always boolean
// do something
} I'm not opposed to a config param here, but it's not obvious to me how to store state as a number, and retrieve it as a boolean. Except maybe a selector of some kind? A hint here would be interesting for me. |
…odule, and global
^^ poke? |
Sorry, I'll need a bit more time. I'll try to get back to you later this evening. |
I think both solutions can co-exist. I came up with something like this: const createLoadingAction = (valueFn) =>
(show) =>
(state, { name, action }: any) => ({
...state,
global: valueFn[show](state.global),
models: {
...state.models,
[name]: valueFn[show](state.models[name]),
},
effects: {
...state.effects,
[name]: {
...state.effects[name],
[action]: valueFn[show](state.effects[name][action]),
},
},
})
let valueFn
let defaultValue
if (config.valueType === 'number') {
valueFn = {
hide: () => 0,
show: (v) => v + 1,
}
defaultValue = 0
} else {
valueFn = {
hide: () => false,
show: () => true,
}
defaultValue = false
}
const loadingAction = createLoadingAction(valueFn)
const loading: Model = {
name: loadingModelName,
reducers: {
hide: loadingAction('hide'),
show: loadingAction('show'),
},
state: {
effects: {},
global: defaultValue,
models: {},
},
}
/* add defaultValue where needed */ In this case, users can opt in to using numbers over booleans by adding a This way, TypeScript/Flow folks are happy, no breaking changes, and the README can emphasize that numbers are an excellent option. What do you think? |
Interesting idea! Feels pretty complicated but it's an interesting concept, I'll try to take a look this weekend. Also, I think the numerical |
Great, also have a look at #266. Can you think of a way to resolve this with the loading plugin? |
|
||
const loadingModelName = config.name || 'loading' | ||
|
||
const converter = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm pretty happy with this solution, it keeps a "background" counter called cntState
of dispatched effects, but converts it onto its public state as either a number or boolean.
@@ -0,0 +1,327 @@ | |||
const delay = ms => new Promise(r => setTimeout(r, ms)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are a lot more tests now.. I just duplicated them and tested for boolean in one file, and number in this one.
@@ -62,21 +62,28 @@ init({ | |||
|
|||
## Options | |||
|
|||
### name | |||
### asNumber |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yay for docs! 👍
@@ -6,7 +6,7 @@ import createLoadingPlugin from '@rematch/loading' | |||
import App from './App' | |||
import example from './example' | |||
|
|||
const loadingPlugin = createLoadingPlugin() | |||
const loadingPlugin = createLoadingPlugin({ asNumber: true }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The example uses numbers, I think it's way more practical personally
Quite an elegant solution with the "converter". Thanks for putting in all the effort @crazy4groovy, great work, and sorry this took so long. I really appreciate your patience. |
Getting a strange error from the Rollup bundler.
There is no "parse" in that file. WIll have to look at this tomorrow morning before I'm able to publish as |
Drat sorry. Here's a 100% shot in the dark to try: could be the |
Maybe this issue: rollup/rollup-plugin-commonjs#299 |
Something changed in Rollup. Before I could use the peer dependencies in the root "rematch" directory, but now I had to install them all as dev dependencies in the plugins. |
Thanks for your help. Published as @rematch/[email protected]. |
I was having problems with the loading module resolving a pending effect too early, because out of a batch of dispatched effects, the first completed one set the loading state to
false
.This implements an integer counter instead of a boolean value.
Also cleaned up the plugin tests slightly.