Search code examples
javascriptlaravel-5vue.jsurl-routing

$http.get in Vue.js does not work when view is accessed from resource controller in Laravel


I am facing a confusing JavaSript problem with Vue.js in a Laravel project: The same page works if I route to it directly from routes.php, but it does not if I use the resource controller.

routes.php:

Route::resource('foo', 'FooController');

get('foo_create', function () {
    return view('foo.create');  // works
});

get('foobar_to_fetch', function () {
    return App\Node::all();  // some json
});

FooController.php:

class FooController extends Controller
{
    public function create()
    {
        return view('foo.create');  // broken
    }
}

views/foo/create.php:

<div id="foo">

    <table>
        <tr v-repeat="foobar">
            <td>{{ id }}</td>
            <td>{{ name }}</td>
        </tr>
    </table>

    <pre>{{ $data | json }}</pre>

</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/0.11.10/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-resource/0.1.16/vue-resource.min.js"></script>
<script src="http://localhost/foo/resources/views/foo/create.js"></script>

views/foo/create.js:

new Vue({

    el: '#foo',

    data: {
        foobar: []
    },

    ready: function() {
        this.fetchFoobar();
    },

    methods: {
        fetchFoobar: function () {
            alert('no problem until here');
            this.$http.get('foobar_to_fetch', function (foobar_fetched) {
                alert(foobar_fetched.length);
                this.foobar = foobar_fetched;
            })
        }
    }

});

If I go to /foo_create I see the two alerts and the table with the fetched data. If I go to /foo/create (which is of course what I want) I see only the first alert and nothing more.

I found out that it works in both cases if I give $http.get the full path:

this.$http.get('http://localhost/foo/public/index.php/foobar_to_fetch', function (foobar_fetched) {

But how is it possible that the same page behaves differently, depending on how I got there?

Where does $http.get look if it is told to look for 'foobar_to_fetch' and the page is accessed as /foo/create? And is there a relative path that would work in this case?


Solution

  • Try:

    methods: {
            fetchFoobar: function () {
                alert('no problem until here');
                this.$http.get('/foobar_to_fetch', function (foobar_fetched) {
                    alert(foobar_fetched.length);
                    this.foobar = foobar_fetched;
                })
            }
        }
    

    depending on where you triggered this get request, it will change the url because 'foobar_to_fetch' is a relative url and '/foobar_to_fetch' is absolute compared to the domain name.

    You can also detect this by opening the network console ( on Chrome ) and check out the headers sent by the Ajax request.