1

Let's say I have this html:

<div id="app">
        <h2>List of Products</h2>
        <table border="1">
            <thead>
            <tr>
                <th>Name</th>
                <th>Price</th>
                <th>Category</th>
            </tr>
            </thead>
            <tbody>
            <tr v-for="product in products">
                <td>${product.name}$</td>
                <td>${product.price}$</td>
                <td>${product.category}$</td>
            </tr>
            </tbody>
        </table>
</div>

And a Vue script like this:

        var app = new Vue({
            delimiters: ['${', '}$'],
            el: '#app',
            data: {
                //instead of this hardcoded result I'd like to get this array after sending a request
                products: [
                    { name: "Keyboard", price: 44, category: 'Accessories'},
                    { name: "Mouse", price: 20, category: 'Accessories'},
                    { name: "Monitor", price: 399, category: 'Accessories'},
                    { name: "Dell XPS", price: 599, category: 'Laptop'},
                    { name: "MacBook Pro", price: 899, category: 'Laptop'},
                    { name: "Pencil Box", price: 6, category: 'Stationary'},
                    { name: "Pen", price: 2, category: 'Stationary'},
                    { name: "USB Cable", price: 7, category: 'Accessories'},
                    { name: "Eraser", price: 2, category: 'Stationary'},
                    { name: "Highlighter", price: 5, category: 'Stationary'}
                ]
            },
        });

How do I send a request with AJAX to get the products object list and pass it on to Vue to render it after the result comes back from the request?

I would've imagined something like this, but this does not work:

        let products;
        function getHello() {

            var ajaxSendRequest = $.ajax({
                url: '{{ path('get_products') }}',
                type: 'GET',
                dataType: 'json'
            });
            ajaxSendRequest.done(function (data) {
                //set the products variable to data that comes from response
                products = data;
            }).fail(function (textStatus, errorThrown) {

            });
        }
    
//after this use it in vue

I do not have much experience with stuff like this, so if this cannot be done, what is the right way to accomplish the same thing? (get data from api and then render it)

2 Answers 2

2

You should first create a Vue method for your ajax code.

Methods are defined within your app like this:

methods: {
    getHello() {
        ...
    }
},

The methods property goes inside your Vue instance, same as data, etc.

Once it's there, you can set your products by access this.products where this refers to the Vue instance of that component.

For example

methods: {
    getHello() {
        ...
        this.products = ajaxResponse;
    }
},

Then you simply use the products data variable within your Vue component and it is "reactive" meaning that Vue automatically tracks and updates when it is changed.

However, there's a problem. Your method you have uses a callback. From within the callback, this won't refer to the Vue instance so instead you need to do something like this

methods: {
    getHello() {
        const $vm = this;
        ...
            // Inside your callback
            $vm.products = ajaxResponse;
    }
},

This allows us to set a locally scoped version of this that refers back to the Vue instance and access it inside our callback where the Vue this would have been overwritten

You would then call this method inside the mounted() lifecycle hook:

mounted() {
    this.getHello();
}
Sign up to request clarification or add additional context in comments.

Comments

-1

As simple as retrieving the data, and displaying the list. Vue will render the items, when they are ready. The this example: Vue SFC Playground

<template>
        <h2>List of Products</h2>
        <table border="1">
            <thead>
            <tr>
                <th>Name</th>
                <th>Price</th>
                <th>Category</th>
            </tr>
            </thead>
            <tbody>
            <tr v-for="(product, index) in localProducts" :key="index">
                <td>{{product.name}}</td>
                <td>{{product.price}}</td>
                <td>{{product.category}}</td>
            </tr>
            </tbody>
        </table>
</template>

<script>
import { defineComponent } from "vue";
export default defineComponent({
  mounted(){
      setTimeout(() => {
        this.localProducts = this.serverProducts
      }, 3000)
  },
  data() {
    return {
      localProducts: undefined,
      serverProducts: [
        { name: "Keyboard", price: 44, category: 'Accessories'},
        { name: "Mouse", price: 20, category: 'Accessories'},
        { name: "Monitor", price: 399, category: 'Accessories'},
        { name: "Dell XPS", price: 599, category: 'Laptop'},
        { name: "MacBook Pro", price: 899, category: 'Laptop'},
        { name: "Pencil Box", price: 6, category: 'Stationary'},
        { name: "Pen", price: 2, category: 'Stationary'},
        { name: "USB Cable", price: 7, category: 'Accessories'},
        { name: "Eraser", price: 2, category: 'Stationary'},
        { name: "Highlighter", price: 5, category: 'Stationary'}
      ]
    }
  }
});
</script>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.