-
Notifications
You must be signed in to change notification settings - Fork 1
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
feat: add base logic for getting Topics via redux #11
Conversation
src/reducers/topics.reducer.js
Outdated
switch (action.type) { | ||
case TOPICS_GET_REQUEST: | ||
//TODO add ..state, and tests! | ||
//TODO add thunk as redux-observable is out of order :( |
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!
… properly dispatch actions in correct order
@@ -3,7 +3,8 @@ module.exports = { | |||
'browser': true, | |||
'commonjs': true, | |||
'jasmine': true, | |||
'es6': true | |||
'es6': true, | |||
'jest/globals': 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.
cool! WebStrom won't underline these globals?
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.
yes! :) (describe/it only tho:)
package.json
Outdated
@@ -9,6 +9,8 @@ | |||
"react-redux": "^5.0.7", | |||
"react-scripts": "1.1.4", | |||
"redux": "^4.0.0", | |||
"redux-thunk": "^2.2.0", | |||
"rxjs": "^6.2.0", |
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.
is RX needed if we have redux-thunk
?
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 see we don't import anything from this library, so I guess you pushed it accidentally
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.
you are right, thanks!
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 need to investigate it further, as without it lint-stage is throwing this error:
lint-staged/lint-staged#416
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.
fixed in 7646cd7
Please note that in my case it was necessary to totally remove lint-staged
from both node_modules and package.json and install it again :(
return TopicService.getSubmittedTopics().then(topics => { | ||
dispatch(topicsFetched(topics)); | ||
}).catch(error => { | ||
dispatch(topicsFetchError(error)); |
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.
props for error handling 👍
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.
it is not reflected anywhere in the app yet - I suppose it would be great to use some Toast/SnackBars to show them!
@@ -38,7 +38,7 @@ TopBar.propTypes = { | |||
}; | |||
|
|||
const mapStateToProps = state => ({ | |||
loggedUser: state.loggedUser | |||
loggedUser: state.auth.loggedUser |
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.
yeah, better use this scopes
compose( | ||
applyMiddleware( | ||
thunk), | ||
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__() |
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.
using window
, super pure!
|
||
describe('payload received', () => { | ||
const payload = [TopicModel.fromBackendData({})]; | ||
const topicState = topicReducer({pending: true}, topicsFetched(payload)); |
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.
aha! I guess it was the initial state, so maybe empty object in previous cases (no preference here, I just want to open a discussion how to make this in a best way)
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.
Passing null
would actually break the reducer state - as first argument would be null, then default assignment is not used (fun(arg=default, ...) { ...}
), therefore it would blow the whole reducer (try to change undefined to null - reducer always return null instead of initialState)
Empty object {}
works the same - no initialState is used. We could just pass initialState
which is already exported but I am not sure if it gives us a real value. What do you think?
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.
yeah, good idea!
case LOGIN: | ||
return Object.assign({}, state, { loggedUser: true }); | ||
case LOGOUT: | ||
return Object.assign({}, state, { loggedUser: false }); |
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.
yeh, we stay with es6. I saw recently what problems can there be with Object Rest/Spread is still a proposal! https://github.com/tc39/proposal-object-rest-spread CC: @ulaulala
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.
Interesting, I haven't know about any bugs for that. @Tuhaj could you please elaborate more? If I understood correctly from this issue (tc39/proposal-object-rest-spread#52) it uses Object.assign under the hood.
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.
@kgajowy No bugs, but a lot of bother in case of deploy on SOME platforms. We recently tried to deploy a node app on Azure, and guess what happened: transpilers needed. Luckly on Heroku it went without any problems.
* 2) while using a dive, we have actions called immediately which may not be what we want | ||
* | ||
* I picked 2) as using 1) would only tell us that prop is called but we would lose the assurance that | ||
* Container is correctly 'connected' (i.e. has correctly mapped dispatchToProps |
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.
interesting, have you experienced some bugs with wrongly connected components 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.
@Tuhaj lets say so - lack of correct mapping or lack of connect
at all :)
}); | ||
|
||
it('should have topics array connected correctly from redux', () => { | ||
expect(wrapper.instance().props.topics).toBe(initialState.topic.topics); |
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 still confuses me, .props().topics
won't work here?
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 full example is provided there http://airbnb.io/enzyme/docs/api/ShallowWrapper/props.html
I think it is worth reading but to make it short: wrapper.props()
returns only those props that are directly mentioned within the construction of <Component props....)
- while we have some props that are connect
ed by the Redux! thus:
const mapStateToProps = ({ topic }) => ({
topics: topic.topics,
pending: topic.pending,
error: topic.error
});
no prop from those will be visible in wrapper.props()
!
so in fact, we actually could pass all props instead of the store there... but it would be a test that doesnt actually test if our component builds correctly in connection to the Redux
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.
thanks for explanation!
@@ -41,4 +46,14 @@ describe('<TopicsList>', () => { | |||
}); | |||
}); | |||
|
|||
describe('when topics are loading', () => { | |||
beforeEach(() => { | |||
wrapper = shallow(<TopicsList pending={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.
const
missing
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 don't think it is necessary. let wrapper
is defined at the very beginning of the test. Or you mean sosmething else than const wrapper
? (btw it wouldn't be visible in the test later or, so rather let wrapper
inside describe but this is already done above)
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.
eh, haven't noticed /shrug leave it
Added: