Skip to content
This repository has been archived by the owner on Feb 22, 2023. It is now read-only.

Use Vuex map- helpers in components #242

Merged
merged 18 commits into from
Sep 23, 2021
Merged

Conversation

obulat
Copy link
Contributor

@obulat obulat commented Sep 18, 2021

Fixes

Related #205 by @dhruvkb and #229 by @obulat

Description

In an attempt to break the huge #229 into two parts, I extracted all the changes in the components into this PR.

Technical details

This PR contains many small refactorings replacing direct store calls (this.$store.dispatch('actionName')) with mapped versions (mapActions, mapMutations and mapState) in order to simplify component code.
Some actions here use a seemingly unnecessary string interpolation (this.commit(`${MUTATION_NAME_CONSTANT}`)). In fact, they are left this way to make adding module name easier in #229.

Checklist

  • My pull request has a descriptive title (not a vague title like Update index.md).
  • My pull request targets the default branch of the repository (main or master).
  • My commit messages follow best practices.
  • My code follows the established code style of the repository.
  • I added or updated tests for the changes I made (if applicable).
  • I added or updated documentation (if applicable).
  • I tried running the project locally and verified that there are no visible errors.

Developer Certificate of Origin

Developer Certificate of Origin
Developer Certificate of Origin
Version 1.1

Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
1 Letterman Drive
Suite D4700
San Francisco, CA, 94129

Everyone is permitted to copy and distribute verbatim copies of this
license document, but changing it is not allowed.


Developer's Certificate of Origin 1.1

By making a contribution to this project, I certify that:

(a) The contribution was created in whole or in part by me and I
    have the right to submit it under the open source license
    indicated in the file; or

(b) The contribution is based upon previous work that, to the best
    of my knowledge, is covered under an appropriate open source
    license and I have the right under that license to submit that
    work with modifications, whether created in whole or in part
    by me, under the same open source license (unless I am
    permitted to submit under a different license), as indicated
    in the file; or

(c) The contribution was provided directly to me by some other
    person who certified (a), (b) or (c) and I have not modified
    it.

(d) I understand and agree that this project and the contribution
    are public and that a record of the contribution (including all
    personal information I submit with it, including my sign-off) is
    maintained indefinitely and may be redistributed consistent with
    this project or the open source license(s) involved.

@obulat obulat requested a review from a team as a code owner September 18, 2021 07:26
@obulat obulat requested review from krysal and dhruvkb September 18, 2021 07:26
@obulat obulat added ✨ goal: improvement Improvement to an existing user-facing feature 💻 aspect: code Concerns the software code in the repository labels Sep 18, 2021
Copy link
Member

@zackkrida zackkrida left a comment

Choose a reason for hiding this comment

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

I've tested this a ton locally, everything is working great 😻

Copy link
Member

@dhruvkb dhruvkb left a comment

Choose a reason for hiding this comment

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

This is a very massive undertaking. Thanks for simplifying this!

I've pointed out some changes, mostly including stylistic changes but one bug as well. These occur several times in the PR but I'm only highlighting one occurrence for brevity.

return this.$store.state.audios
},
...mapState({
audios: (state) => state.audios,
Copy link
Member

Choose a reason for hiding this comment

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

Arrow functions that map to state properties can be replaced with strings:

Suggested change
audios: (state) => state.audios,
audios: 'audios',

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The strings do not work for namespaced stores, so for consistency I used the same syntax everywhere.
I thought that only Webstorm for some reason doesn't like dots in mapState (and warns about them), but apparently it's a Vuex limitation, see vuejs/vuex#459 and vuejs/vuex#1592

Copy link
Member

Choose a reason for hiding this comment

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

For namespaced stores, the syntax is to use /, not . as the separator.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tried out different versions of state mapping in both WebStorm and Visual Studio Code, here are some results I get:

  • ...mapState(REPORT_CONTENT, { isReportFormVisible: 'isReportFormVisible' })
    (+) Clear, easy to set for namespaced modules.
    (-) Error-prone: No autocomplete in either WebStorm or Visual Studio Code, the property is not a constant
    (-) Webstorm shows a warning about 'isReportFormVisible': "Cannot resolve Vuex state isReportFormVisible"
    (-) Not clear if it works for nested objects

  • ...mapState(REPORT_CONTENT, { isReportFormVisible: (state) => state.isReportFormVisible, }),
    (-) Verbose
    (+) Easier to avoid errors: both WebStorm and Visual Studio Code autocomplete the property after the dot (isReportFormVisible)
    (+) No warnings.

  • ...mapState(REPORT_CONTENT, ['isReportFormVisible'])
    (+) Short
    (-) Error prone: No autocomplete in either WebStorm or Visual Studio Code, the property is not a constant
    (-) WebStorm warns that it "Cannot resolve Vuex state isReportFormVisible".
    (-) Does not work well for nested objects (such as the query object in the search store)

src/components/AudioResultsList.vue Show resolved Hide resolved
Comment on lines 94 to 96
...mapActions({
fetchMedia: `${FETCH_MEDIA}`,
}),
Copy link
Member

Choose a reason for hiding this comment

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

src/components/Filters/FilterChecklist.vue Outdated Show resolved Hide resolved
src/components/Filters/FilterDisplay.vue Outdated Show resolved Hide resolved
@dhruv
Copy link

dhruv commented Sep 20, 2021

Please correct @dhruvkb's handle in the PR description.

obulat and others added 5 commits September 20, 2021 21:38
Co-authored-by: Dhruv Bhanushali <dhruv_b@live.com>
# Conflicts:
#	src/components/NotificationBanner.vue
#	src/pages/search.vue
Make most of the Vuex store modules namespaced
@obulat obulat mentioned this pull request Sep 21, 2021
7 tasks
# Conflicts:
#	src/store-modules/related-media-store.js
#	src/store-modules/search-store.js
Copy link
Member

@dhruvkb dhruvkb left a comment

Choose a reason for hiding this comment

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

Really massive undertaking with a lot of code quality improvements!

There are still a large number of direct calls to $store.state, $store.dispatch etc. Are they intentionally not using map* helpers?

@@ -107,7 +107,7 @@ export default {
)
// Sync status from store to parent
watch(
() => [store.state.activeMediaType, store.state.activeMediaId],
() => [store.state['active-media'].type, store.state['active-media'].id],
Copy link
Member

@dhruvkb dhruvkb Sep 22, 2021

Choose a reason for hiding this comment

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

Does Nuxt automatically use the file name? Can we use the activeMedia name for the module to avoid []?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Unfortunately, yes, Nuxt uses the file name, and we cannot use the camelCased version. We could rename the store module to active

Copy link
Member

Choose a reason for hiding this comment

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

That'll be a good idea! I would've liked if Nuxt offered to option to name the state but we've got to work with what we have.

state.active will be better than state['active-media'].

@obulat
Copy link
Contributor Author

obulat commented Sep 23, 2021

Really massive undertaking with a lot of code quality improvements!

There are still a large number of direct calls to $store.state, $store.dispatch etc. Are they intentionally not using map* helpers?

Yes, they are not using map* helpers because I haven't figured out how to test them. In tests, Vuex cannot find namespaced modules when map* helpers are used with module name, eg. mapActions(RELATED, {setRelatedMedia: SET_RELATED_MEDIA})

@obulat obulat merged commit 0449037 into main Sep 23, 2021
@obulat obulat deleted the use_map_helpers_in_components branch September 23, 2021 10:09
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
💻 aspect: code Concerns the software code in the repository ✨ goal: improvement Improvement to an existing user-facing feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants