最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Format Column Data before passing to Vue Good-Table - Stack Overflow

programmeradmin1浏览0评论

I've built a Vue.js ponent, which fetches orders from a Woomerce store. These orders contain the product variations from the products and are received as an object.

In the table, I need to format the object before it is displayed.

My code looks like this:

<template>
<div>

    <vue-good-table
      title=""
      :columns="columns"
      :rows="variationOrders"
      :paginate="true"
      :lineNumbers="true"/>

</div>
</template>

<script>
    export default {
        data: function() {
            return {
                variationOrders: [],
                columns: [
                {
                  label: 'Order#',
                  field: 'order_id',
                  filterable: true,
                },
                {
                  label: 'Customer',
                  field: 'customer_name',
                  //type: 'number',
                  html: false,
                  filterable: true,
                },
                {
                  label: 'QTY',
                  field: 'qty',
                  type: 'number',
                  //inputFormat: 'YYYYMMDD',
                  //outputFormat: 'MMM Do YY',
                },
                {
                  label: 'Product',
                  field: 'product_name',
                  //type: 'percentage',
                  html: false,
                },
                {
                  label: 'Variations',
                  field: this.formatVariations(self.variationOrders),
                  //type: 'percentage',
                  html: true,
                },
                {
                  label: 'Timeslot',
                  field: 'timeslot',
                  //type: 'percentage',
                  html: false,
                },
                {
                  label: 'Transportation',
                  field: 'store_id',
                  //type: 'percentage',
                  html: false,
                },
              ],
            }
        },
        methods: {
            getTotals: function() {
                var self = this;
                var productId = document.getElementById('product-id').getAttribute('data-id');
                axios.get('/api/v1/order_variations/' + productId)
                .then(function (response) {
                    self.variationOrders = response.data.order_variations;
                    //console.log(response.data);
                })
                .catch(function(error) {
                    //
                });
            },
            formatVariations: function(variationOrders) {
              console.log(variationOrders);
            },
        },
        mounted: function() {
            this.getTotals();
            // call the API every 30 seconds to fetch new orders
            setInterval(function () {
                this.getTotals();
            }.bind(this), 5000); 
        }
    }
</script>

On the Variations column I pass a function which is responsible for formatting the string. The function itself works fine, but I am unable to pass the the received object from the API to this function.

I get the following error message in the console:

  1. If I pass this.formatVariations(this.variationOrders) and console.log I get undefined

  2. If I pass this.formatVariations(variationOrders) and console.log I get [Vue warn]: Error in data(): "ReferenceError: variationOrders is not defined"

I have a suspicion that at the time the function is called, that variable doesn't exist yet.

Is there anything I'm missing?

UPDATE 1

I've updated the code to the following. I'm closer but unfortunately the view isn't updating.

MY code looks like this:

<template>
<div>

    <vue-good-table
      title=""
      :columns="formattedColumns"
      :rows="variationOrders"
      :paginate="true"
      :lineNumbers="true"/>

</div>
</template>

<script>
    export default {
        data: function() {
            return {
                variationOrders: [],
                columns: [
                {
                  label: 'Order#',
                  field: 'order_id',
                  filterable: true,
                },
                {
                  label: 'Customer',
                  field: 'customer_name',
                  //type: 'number',
                  html: false,
                  filterable: true,
                },
                {
                  label: 'QTY',
                  field: 'qty',
                  type: 'number',
                  //inputFormat: 'YYYYMMDD',
                  //outputFormat: 'MMM Do YY',
                },
                {
                  label: 'Product',
                  field: 'product_name',
                  //type: 'percentage',
                  html: false,
                },
                {
                  label: 'Variations',
                  field: 'variation',
                  //type: 'percentage',
                  html: true,
                },
                {
                  label: 'Timeslot',
                  field: 'timeslot',
                  //type: 'percentage',
                  html: false,
                },
                {
                  label: 'Transportation',
                  field: 'store_id',
                  //type: 'percentage',
                  html: false,
                },
              ],
            }
        },
        methods: {
            getTotals: function() {
                var self = this;
                var productId = document.getElementById('product-id').getAttribute('data-id');
                axios.get('/api/v1/order_variations/' + productId)
                .then(function (response) {
                    self.variationOrders = response.data.order_variations;
                })
                .catch(function(error) {
                    //
                });
            },
            formatVariations: function(variationOrders) {
              var variationsString = '';
              variationOrders.forEach(function(item) {
                var variations = JSON.parse(item.variation);
                for(var i = 0; i < variations.length; i++) {
                  variationsString = variationsString + variations[i].key + ': ' + variations[i].value + '<br />';
                }
              });
              return variationsString;
            },
        },
        puted: {
          formattedColumns(){
            const formattedVariations = this.formatVariations(this.variationOrders);
            console.log(formattedVariations);
            return this.columns.map(c => {
              if (c.label == "Variations") {
                return {label: "Variations", field: formattedVariations , html: true}
              }
              return c;
            })
          }
        },
        mounted: function() {
            this.getTotals();
            // call the API every 30 seconds to fetch new orders
            setInterval(function () {
                this.getTotals();
            }.bind(this), 5000); 
        },
    }
</script>

Update 2

The formatVariations() function returns a sample set like this:

choose-your-cake: Naked<br />choose-sugar: Yes<br />choose-your-cake: Naked<br />choose-sugar: No<br />choose-your-cake: Naked<br />choose-sugar: No<br />choose-your-cake: Naked<br />choose-sugar: Yes<br />choose-your-cake: Naked<br />choose-sugar: Yes<br />choose-your-cake: Coated<br />choose-sugar: No<br />choose-your-cake: Naked<br />choose-sugar: Yes<br />choose-your-cake: Naked<br />choose-sugar: Yes<br />choose-your-cake: Coated<br />choose-sugar: Yes<br />choose-your-cake: Naked<br />choose-sugar: Yes<br />choose-your-cake: Naked<br />choose-sugar: Yes<br />choose-your-cake: Naked<br />choose-sugar: Yes<br />

Update 3

Here's one array item of what the API returns:

:
customer_name
:
(...)
order_id
:
(...)
product_name
:
(...)
qty
:
(...)
store_id
:
(...)
variation
:
"[{"id": 35, "key": "choose-your-cake", "value": "Naked"}, {"id": 36, "key": "choose-sugar", "value": "Yes"}]"

I've built a Vue.js ponent, which fetches orders from a Woomerce store. These orders contain the product variations from the products and are received as an object.

In the table, I need to format the object before it is displayed.

My code looks like this:

<template>
<div>

    <vue-good-table
      title=""
      :columns="columns"
      :rows="variationOrders"
      :paginate="true"
      :lineNumbers="true"/>

</div>
</template>

<script>
    export default {
        data: function() {
            return {
                variationOrders: [],
                columns: [
                {
                  label: 'Order#',
                  field: 'order_id',
                  filterable: true,
                },
                {
                  label: 'Customer',
                  field: 'customer_name',
                  //type: 'number',
                  html: false,
                  filterable: true,
                },
                {
                  label: 'QTY',
                  field: 'qty',
                  type: 'number',
                  //inputFormat: 'YYYYMMDD',
                  //outputFormat: 'MMM Do YY',
                },
                {
                  label: 'Product',
                  field: 'product_name',
                  //type: 'percentage',
                  html: false,
                },
                {
                  label: 'Variations',
                  field: this.formatVariations(self.variationOrders),
                  //type: 'percentage',
                  html: true,
                },
                {
                  label: 'Timeslot',
                  field: 'timeslot',
                  //type: 'percentage',
                  html: false,
                },
                {
                  label: 'Transportation',
                  field: 'store_id',
                  //type: 'percentage',
                  html: false,
                },
              ],
            }
        },
        methods: {
            getTotals: function() {
                var self = this;
                var productId = document.getElementById('product-id').getAttribute('data-id');
                axios.get('/api/v1/order_variations/' + productId)
                .then(function (response) {
                    self.variationOrders = response.data.order_variations;
                    //console.log(response.data);
                })
                .catch(function(error) {
                    //
                });
            },
            formatVariations: function(variationOrders) {
              console.log(variationOrders);
            },
        },
        mounted: function() {
            this.getTotals();
            // call the API every 30 seconds to fetch new orders
            setInterval(function () {
                this.getTotals();
            }.bind(this), 5000); 
        }
    }
</script>

On the Variations column I pass a function which is responsible for formatting the string. The function itself works fine, but I am unable to pass the the received object from the API to this function.

I get the following error message in the console:

  1. If I pass this.formatVariations(this.variationOrders) and console.log I get undefined

  2. If I pass this.formatVariations(variationOrders) and console.log I get [Vue warn]: Error in data(): "ReferenceError: variationOrders is not defined"

I have a suspicion that at the time the function is called, that variable doesn't exist yet.

Is there anything I'm missing?

UPDATE 1

I've updated the code to the following. I'm closer but unfortunately the view isn't updating.

MY code looks like this:

<template>
<div>

    <vue-good-table
      title=""
      :columns="formattedColumns"
      :rows="variationOrders"
      :paginate="true"
      :lineNumbers="true"/>

</div>
</template>

<script>
    export default {
        data: function() {
            return {
                variationOrders: [],
                columns: [
                {
                  label: 'Order#',
                  field: 'order_id',
                  filterable: true,
                },
                {
                  label: 'Customer',
                  field: 'customer_name',
                  //type: 'number',
                  html: false,
                  filterable: true,
                },
                {
                  label: 'QTY',
                  field: 'qty',
                  type: 'number',
                  //inputFormat: 'YYYYMMDD',
                  //outputFormat: 'MMM Do YY',
                },
                {
                  label: 'Product',
                  field: 'product_name',
                  //type: 'percentage',
                  html: false,
                },
                {
                  label: 'Variations',
                  field: 'variation',
                  //type: 'percentage',
                  html: true,
                },
                {
                  label: 'Timeslot',
                  field: 'timeslot',
                  //type: 'percentage',
                  html: false,
                },
                {
                  label: 'Transportation',
                  field: 'store_id',
                  //type: 'percentage',
                  html: false,
                },
              ],
            }
        },
        methods: {
            getTotals: function() {
                var self = this;
                var productId = document.getElementById('product-id').getAttribute('data-id');
                axios.get('/api/v1/order_variations/' + productId)
                .then(function (response) {
                    self.variationOrders = response.data.order_variations;
                })
                .catch(function(error) {
                    //
                });
            },
            formatVariations: function(variationOrders) {
              var variationsString = '';
              variationOrders.forEach(function(item) {
                var variations = JSON.parse(item.variation);
                for(var i = 0; i < variations.length; i++) {
                  variationsString = variationsString + variations[i].key + ': ' + variations[i].value + '<br />';
                }
              });
              return variationsString;
            },
        },
        puted: {
          formattedColumns(){
            const formattedVariations = this.formatVariations(this.variationOrders);
            console.log(formattedVariations);
            return this.columns.map(c => {
              if (c.label == "Variations") {
                return {label: "Variations", field: formattedVariations , html: true}
              }
              return c;
            })
          }
        },
        mounted: function() {
            this.getTotals();
            // call the API every 30 seconds to fetch new orders
            setInterval(function () {
                this.getTotals();
            }.bind(this), 5000); 
        },
    }
</script>

Update 2

The formatVariations() function returns a sample set like this:

choose-your-cake: Naked<br />choose-sugar: Yes<br />choose-your-cake: Naked<br />choose-sugar: No<br />choose-your-cake: Naked<br />choose-sugar: No<br />choose-your-cake: Naked<br />choose-sugar: Yes<br />choose-your-cake: Naked<br />choose-sugar: Yes<br />choose-your-cake: Coated<br />choose-sugar: No<br />choose-your-cake: Naked<br />choose-sugar: Yes<br />choose-your-cake: Naked<br />choose-sugar: Yes<br />choose-your-cake: Coated<br />choose-sugar: Yes<br />choose-your-cake: Naked<br />choose-sugar: Yes<br />choose-your-cake: Naked<br />choose-sugar: Yes<br />choose-your-cake: Naked<br />choose-sugar: Yes<br />

Update 3

Here's one array item of what the API returns:

:
customer_name
:
(...)
order_id
:
(...)
product_name
:
(...)
qty
:
(...)
store_id
:
(...)
variation
:
"[{"id": 35, "key": "choose-your-cake", "value": "Naked"}, {"id": 36, "key": "choose-sugar", "value": "Yes"}]"
Share Improve this question edited Oct 12, 2017 at 15:19 Marcus Christiansen asked Oct 12, 2017 at 12:03 Marcus ChristiansenMarcus Christiansen 3,2079 gold badges52 silver badges93 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 7

self.variationOrders is undefined in the data method; self is only available in the scope of the getTotals method.

Instead, use a puted property to format columns.

puted:{
  formattedColumns(){
    const formattedVariations = this.formatVariations(this.variationOrders)
    return this.columns.map(c => {
      if (c.label === "Variations")
        return {label: "Variations", field: formattedVariations , html: true}

      return c
    })
  }
}

And use the puted property in the template.

<vue-good-table
  title=""
  :columns="formattedColumns"
  :rows="variationOrders"
  :paginate="true"
  :lineNumbers="true"/>

The puted property should be updated whenever variationOrders changes.

Edit

The above answers the question that was asked, but doesn't actually render the desired table (as I understand it). This is because of a misunderstanding in how vue-good-table works.

If I understand correctly, what OP really wants is for the content of the cell in the table to be formatted with HTML. In order to do that, you simply need to use the scoped slot table-row. Here is how the template should look (the columns are abbreviated for this example).

<vue-good-table
  title=""
  :columns="columns"
  :rows="variationOrders"
  :paginate="true"
  :lineNumbers="true">
  <template slot="table-row" scope="props">
    <td>{{ props.row.order_id }}</td>
    <td>{{ props.row.customer_name }}</td>
    <td><span v-html="formatVariations(props.row.variation)"></span></td>
  </template>
</vue-good-table>

I also updated the formatVariations method:

formatVariations: function(variationOrders) {
  let parsed = JSON.parse(variationOrders).map(order => {
    return `${order.key} : ${order.value} <br>`
  })
  return parsed.join('');
},

This is assuming the data format looks like this:

[
  {
    order_id: 1,
    customer_name: "Bob NewHart",
    qty: 10,
    product_name: "Hats",
    variation: '[{"id": 35, "key": "choose-your-cake", "value": "Naked"}, {"id": 36, "key": "choose-sugar", "value": "Yes"}]'
  },
  {
    order_id: 2,
    customer_name: "Mary Lamb",
    qty: 10,
    product_name: "Necklaces",
    variation: '[{"id": 35, "key": "choose-your-cake", "value": "Naked"}, {"id": 36, "key": "choose-sugar", "value": "Yes"}]'
  },
]
发布评论

评论列表(0)

  1. 暂无评论