Skip to content
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(MdTable): Implement an asynchronous table #1621

Closed
wants to merge 11 commits into from

Conversation

emman27
Copy link
Contributor

@emman27 emman27 commented Mar 23, 2018

An initial implementation of a table with data hosted on a JSON endpoint.

  • Fetches from endpoint
  • Allows using a nested data structure
  • Allows custom headers
  • Allows custom parameters in the querystring of the request
  • Link up with pagination

package.json Outdated
"dependencies": {},
"dependencies": {
"axios": "^0.18.0"
},
Copy link
Member

Choose a reason for hiding this comment

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

why axios changed to dependencies?

Copy link
Contributor Author

@emman27 emman27 Mar 23, 2018

Choose a reason for hiding this comment

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

Could potentially just use native fetch, tho fetch isn't supported in all browsers. Any other preferences?

Copy link
Member

Choose a reason for hiding this comment

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

I mean all modules imported are in devDependencies for now.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm. I think if there is going to be to support a http client natively to this project, then the client used internally needs to be either a dependency or a peer dependency. Adding as dev dependency will eventually result in it not being installed by npm install vue-material, which may cause confusion for users.

Also open to replacing this with XMLHttpRequest (preferrably not, since this has really fallen out) or fetch (with a polyfill installed as dependency), depending on your team's preference for direction

Copy link
Member

Choose a reason for hiding this comment

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

You don't need to install the modules which vue-material used because the vue-material module you importing is production that already compiled with all modules imported to it.

Copy link
Member

Choose a reason for hiding this comment

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

For example, you can import vue-material without problem if you don't install date-fns and popper.js.

},
asyncHeaders: {
type: Object,
default: () => {}
Copy link
Member

Choose a reason for hiding this comment

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

All vue-material props should be started with prefix md

@@ -296,6 +312,10 @@
// wait for `selectingMode` from `TableRow`
await this.$nextTick()
this.syncSelectedValue()
if (this.asyncUrl) {
const data = (await axios.get(this.asyncUrl, { params: this.asyncParams, headers: this.asyncHeaders })).data
Copy link
Member

Choose a reason for hiding this comment

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

Should there be a loading UI while requesting?
How about a named slot with indeterminate loading bar as default?

@VdustR
Copy link
Member

VdustR commented Mar 23, 2018

@emman27 check list markdown is - [ ], - [x]

@@ -45,6 +45,9 @@
<slot name="md-table-pagination" />
</md-content>

<slot name="md-table-loading"></slot>
Copy link
Member

Choose a reason for hiding this comment

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

only if asyncLoading

@@ -45,6 +45,9 @@
<slot name="md-table-pagination" />
</md-content>

<slot name="md-table-loading"></slot>
<md-progress-bar md-mode="indeterminate" v-if="!$scopedSlots['md-table-loading'] && asyncLoading" />

Copy link
Member

Choose a reason for hiding this comment

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

How about this?

<slot name="md-table-loading" v-if="asyncLoading">
  <md-progress-bar md-mode="indeterminate" />
</slot>

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for helping me out with this! Not extremely familiar with slots myself.

@VdustR
Copy link
Member

VdustR commented Mar 23, 2018

Hey @emman27, would you resolve conflicts? Actually it's better to start from dev branch to make a PR.

@VdustR
Copy link
Member

VdustR commented Mar 23, 2018

You need to fetch current dev before you merge that.

@emman27
Copy link
Contributor Author

emman27 commented Mar 23, 2018

Thanks, was a careless mistake and pushed too early. Fixed now.

@VdustR
Copy link
Member

VdustR commented Mar 23, 2018

Although this is almost completed, I think make v-model like md-options as a Promise in MdAutocomplete might be better for most cases.

@Samuell1
Copy link
Member

Samuell1 commented Mar 23, 2018

Thanks for your first PR! First i think axios should not be a package that we depends on. Best to make it lightweight is to make a callback like md-autocomplete is using.

And please dont use await, async it will broke code - #1182

(If you will be making next PR please follow this guide how to name commits, it will helps us to identify changes + make changelog. https://github.com/vuematerial/vue-material/blob/dev/.github/COMMIT_CONVENTION.md )

@emman27 emman27 changed the title Implement an asynchronous table feat(MdTable) Implement an asynchronous table Mar 23, 2018
@emman27
Copy link
Contributor Author

emman27 commented Mar 23, 2018

Thanks guys, really appreciate what you've built here plus your feedback!

@Samuell1
Copy link
Member

Samuell1 commented Mar 23, 2018

@emman27 Thanks you too for contributing and using Vue Material!

I found there are 2 methods (getModel, getModelItem) that are still pointing to old this.value

And last thing dont forget in that commits naming : after feat(...)

@@ -357,13 +342,14 @@
},
async created () {
Copy link
Member

Choose a reason for hiding this comment

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

I think you forgot to remove async here

@@ -153,7 +158,9 @@
getModel: this.getModel,
getModelItem: this.getModelItem,
selectingMode: null
}
},
items: this.value || [],
Copy link
Member

Choose a reason for hiding this comment

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

I think this should be as Computed

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm I think I'll disagree with this one. This is because we'll have to set the value once the Promise resolves.
Vue recommends not modifying props directly and instead using a data property, or computed if possible. Since there's a set involved, shouldn't data be the more natural choice?

Copy link
Member

Choose a reason for hiding this comment

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

Yes but when i pass my array it will be not reactive to changes because data are changed only on mounted.

And there are few things that you forgot to change 2 methods (getModel, getModelItem) that are still pointing to old this.value

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm good point. I believe this can be resolved by

watch: {
  value() {}
}

as well. Which do you prefer?

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, watch should be good

@emman27 emman27 changed the title feat(MdTable) Implement an asynchronous table feat(MdTable): Implement an asynchronous table Mar 26, 2018
@@ -215,6 +215,7 @@
return { MdTable }
},
watch: {
value() {}, // Watch this prop to make the table reactive to props
Copy link
Member

Choose a reason for hiding this comment

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

This is not finished? You missing here to set value as items.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hey you're right. Now I understand why you suggested computed instead, would probably be cleaner. My apologies. Didn't consider the Promise case :(

@@ -215,7 +215,9 @@
return { MdTable }
},
watch: {
value() {}, // Watch this prop to make the table reactive to props
value() {
if (isPromise(this.value)) this.resolvePromise()
Copy link
Member

Choose a reason for hiding this comment

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

you need to implement else too because all other tables that doesnt use promise are broken.

Copy link
Member

@Samuell1 Samuell1 Mar 28, 2018

Choose a reason for hiding this comment

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

I think better is to make it as computed method, then you can remove items defined in data.

items () {
  if (isPromise(this.value)) {
    return this.resolvePromise()
  } else {
    return this.value
  }
}

Copy link
Member

Choose a reason for hiding this comment

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

There shouldn't be a mutation in a computed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks guys. Care to share the secret of how you guys are so sharp?

@Samuell1 I think that example doesn't work because this.resolvePromise doesn't (and cannot?) return the resolved value.

Copy link
Member

Choose a reason for hiding this comment

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

@emman27 It will work like then((resolve) => (resolve)), but @VdustR said it will be needed to change resolvePromise method.

I think this will now work.

@asadhshujau
Copy link

when will we get pagination feature. waiting for it ...

@dragosct
Copy link
Collaborator

Hi, @emman27! Thanks for your work. Can you please resolve the conflicts to merge this PR?

@emman27
Copy link
Contributor Author

emman27 commented Jun 10, 2020

Hi, @emman27! Thanks for your work. Can you please resolve the conflicts to merge this PR?

Hi @dragosct10, unfortunately I don't quite have the time to work on this these days. I hope the code is still helpful for you guys and feel free to adopt it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants