Vuetable-2: Updating fields on load with a JSON source

Created on 6 May 2017  路  15Comments  路  Source: ratiw/vuetable-2

I am trying to set the fields list, so they load from an external JSON blob and can be changed depending on the form.

I have defined:
:fields="fields"

and set fields = [] in the data blob.

On the mounted and ready, I run the following function:

        getVuetableSchema() {
            axios.get('/api/custom-fields/schema')
                .then(function (response) {
                    this.fields = response.data;
            });
        },

However the table never updates. It appears table fields on the data is still an empty array.

The end point returns:

[{"callback":"","dataClass":"","name":"id","title":"Id","titleClass":"","visible":"true"},{"callback":"","dataClass":"","name":"slug","title":"slug","titleClass":"","visible":"true"}]

and I've also just tried single key values too.

How do I set the fields dynamically for the table, using an external HTTP JSON request?

Most helpful comment

Remember that getVueTableSchema is an async function and you have to call this field reinitialization when you get the response inside then

methods:{
  reinitializeFields(){
    this.$nextTick(()=>{
      this.$refs.vuetable.normalizeFields();
   });
  }
}
//your api call
getVuetableSchema() {
     axios.get('/api/custom-fields/schema')
           .then(response => {
               this.fields = response.data;
               this.reinitializeFields();
     });
},

All 15 comments

You have an anonymous function function (response) which doesn't keep this context from the component. Try

getVuetableSchema() {
            axios.get('/api/custom-fields/schema')
                .then((response)=> {
                    this.fields = response.data;
            });
        },

Thanks. Fields array is populated on the prop:

    fields:Array[2]

    0:Object
    callback:""
    dataClass:""
    name:"id"
    title:"Id"
    titleClass:""
    visible:"true"

    1:Object
    callback:""
    dataClass:""
    name:"slug"
    title:"slug"
    titleClass:""
    visible:"true"
    httpOptions:Object
    params:Object
    loadOnStart:true
    minRows:0
    multiSort:false
    multiSortKey:"alt"
    paginationPath:""
    perPage:10

However the view doesn't update. Data.tablefields shows an empty array still.

screen shot 2017-05-06 at 10 46 52 pm
See attached

You are right. Changing fields dynamically indeed doesn't trigger any updates. I made a very basic fiddle which shows exactly this

I also tried events too, hoping maybe I could force a refresh earlier in the process. For example loading event.

Is it possible to update the tableFields array directly using an override? Quite new to Vue so not sure what scope the data variable sits in. i.e. data.props.fieldTable = response.data ?

@adam-devapp You will need to call normalizeFields() to parse the fields into tableFields. Normally, this is done only once during the created hook. But if you dynamically assigned the fields later, you will have to call normalizeFields() manually.

workaround fiddle

this.fields  = your dynamic fields
this.$nextTick(()=>{
     this.$refs.vuetable.normalizeFields();
})

@ratiw I think adding a watcher on fields internally could be an option. This would allow dynamic field
hide/show. For example many table plugins have the option to chose what columns to display. This could be done easily if fields changes are observed

Setup:

    ready() {
        this.prepareComponent();
    },

    mounted() {
        this.prepareComponent();
    },

Then:

    methods: {

        prepareComponent() {

            this.getVuetableSchema();

            this.$nextTick(()=>{
                this.$refs.vuetable.normalizeFields();
            });

Function:

        getVuetableSchema() {
            axios.get('/api/custom-fields/schema')
                .then(response => {
                    this.fields = response.data;
                });
        },

Still blank. Your method of specifying directly works though. How would I update the above to work through the JSON request?

Remember that getVueTableSchema is an async function and you have to call this field reinitialization when you get the response inside then

methods:{
  reinitializeFields(){
    this.$nextTick(()=>{
      this.$refs.vuetable.normalizeFields();
   });
  }
}
//your api call
getVuetableSchema() {
     axios.get('/api/custom-fields/schema')
           .then(response => {
               this.fields = response.data;
               this.reinitializeFields();
     });
},

Wow. Works. Thank you!!!

@cristijora Hiding/showing fields are already possible with visible option. Adding watcher is possible, just not sure if it will cause any trouble later or not.

Oh ok. Forgot about visible. I think it doesn't make too much sense to add the watcher then.

Thanks guys. Happy with the reinitializeFields() approach above. Simple and code reads well.

Was this page helpful?
0 / 5 - 0 ratings