Skip to content
This repository has been archived by the owner on Aug 5, 2022. It is now read-only.

Week 4: Homework #9

Merged
merged 8 commits into from
Apr 16, 2019
Merged

Week 4: Homework #9

merged 8 commits into from
Apr 16, 2019

Conversation

apedroferreira
Copy link
Contributor

No description provided.

Copy link
Contributor

@dannytce dannytce left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall pretty good! :) There is definitely a lot of space for improvements, but it's something we are about to address in future lessons (side effects most of all).

  1. Personally, I don't like WithConnect name. Maybe Connected${Name} would be better?

  2. And there is one misalignment in the naming of reducer vs. api methods - user vs. customer. I think it should be unified, so let's call our reducer a customer.

  3. Let's add missing functionality - let's save into storage not just token, but the whole user. And also when initialization the store, let's check if user is in the storage

import { setToken } from '../../utils/token'

export const getCustomerToken = async ({ username, password }) => {
const response = await fetch(`${config.apiUrl}/oauth/token`, {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@apedroferreira any chance to use there api/api-client.js?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure! Do you think we should also use the API client for api/get-guest-token.js? Because for this I just followed the same approach as in that file.

Also what do you think about having separate files for get-guest-token and get-customer-token, even though technically they use the same endpoint? Is it the best approach?
I thought about having them in the same file but maybe that would be more confusing for the students.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also this would require some refactoring as currently the API client is for requests that need a token only, and getting the customer token doesn't need one.
So do you think we should refactor the way these methods are working in general so that the API client is used everywhere?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it, now I understand your intention. All good! :)

The best approach would be probably a generic get-token function taking care of both :) But probably let's keep it as it is. @erikmajlath will refactor this together with refresh token handling

src/components/Layout/index.js Outdated Show resolved Hide resolved
src/components/Layout/index.js Outdated Show resolved Hide resolved
isAuthenticated: Object.keys(state.user).length !== 0,
})

const WithConnect = connect(mapStateToProps)(PrivateRoute)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got the intention, but naming is a bit confusing there... Not sure how to resolve it right now, but at least a comment here :D

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also think this is confusing. 😅 I know that my opinion is not going to be popular but...

const WithConnect = connect(mapStateToProps)(Account)

export { WithConnect as Account }

...export default? 🙊🙂Less work, better readability.

export default connect(mapStateToProps)(Account)

I am using the normal export strategy in typescript because when I create files like:

  • models/User
  • models/RefreshToken

Then I can create models/index file:

export * from './RefreshToken'
export * from './User'

And then I can import anything from models by using:

import { User, RefreshToken } from '~/database/sql/models`

This can potentially save couple of lines of code. However, right now we are importing all pages separatelly anyway...

Maybe @varholak-peter can refactor this in his lesson?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like it either. When I moved from default exports to named exports (I will just leave it here for info - https://basarat.gitbooks.io/typescript/docs/tips/defaultIsBad.html) I haven't really used HOCs, because of the hooks.

However what we really don't want to do is to mix default exports with named. We need to keep it consistent.

isAuthenticated: Object.keys(state.user).length !== 0,
})

export default connect(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is gonna be a great candidate for a little compose (from redux) refactor for @varholak-peter 's lesson :)

src/pages/Account/index.js Outdated Show resolved Hide resolved
return (
<Route
{...rest}
render={routeProps => {
if (isAuthenticated) {
return <Component {...routeProps} />
}

return (
<Redirect
to={{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be changed to redirect to login

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aaaand one more thing. Maybe let's extract route names into one file and use them as constants?

}

const mapDispatchToProps = {
login,
Copy link
Contributor

@developer239 developer239 Apr 15, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am probably late to the party but for future reference, I am using mapDispatchToProps like this 🙂

const mapDispatchToProps = {
  dispatchLogin: login,
}

Destructuring props will trigger eslint no-shadow. Here it can actually be confusing to differentiate betwen the two login functions.

https://stackoverflow.com/a/53396094/4766136

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are absolutely right.

What I usually do is to import all actions as follows:

import * as customerActions from '../store/customer/actions'

// and use it

const mapDispatchToProps = {
   login: customerActions.login
}

then when inspecting mapDispatchToProps I immediately know where it is coming from without looking at the import. I also don't favor tying names to the functionality, e.g. I don't want my component to know that this prop is coming from Redux 😄.

What do you think?

@prichodko prichodko changed the title Week 4: Homework (Forms) Week 4: Homework Apr 15, 2019
Copy link
Contributor

@dannytce dannytce left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Legit! Great job with named imports 💪

@dannytce dannytce merged commit 8781930 into master Apr 16, 2019
@dannytce dannytce deleted the week4-homework branch April 16, 2019 08:20
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants