Maxiss
Maxiss

Reputation: 1056

Laravel and vuejs -> how to pass Controller data into my Vue view?

I am discovering php, laravel, vuejs at the same time and I guess there are some things I didn't get well yet ;)

I made a new component "tableau" which is a basic table and would like to use it at many places in my app, where I would just specify its title, columns and data. FootballerController is the place where I get all my data.

Here is what is working now:

app.js

const tableau = new Vue({
    components:{tableau:Tableau
   },
   data: function() {
        return  {
            title: "the best footballers",
            searchQuery: '',
            gridColumns: ['footballer', 'cote', 'nationalite'],
            gridData: [
                { footballer: 'Remond', cote: 951, nationalite:'USA' },
                { footballer: 'Marcel', cote: 935, nationalite:'ESP' },
                { footballer: 'Stian', cote: 923, nationalite:'NOR' },
                { footballer: 'Martin', cote: 923, nationalite:'USA' },
                { footballer: 'Pierre', cote: 918, nationalite:'ESP' },
            ]
        }
   }
}).$mount('#tableau');

footballer.blade.php

<tableau
    v-bind:titre="title"
    :rows="gridData"
    :columns="gridColumns "
    :filter-key="searchQuery" >
  </tableau>

TableauComponent

<template>
    <div >
       <h1 >{{titre}}</h1>
       <table >
            <thead>
            <tr>
                <th v-for="key in columns"
                    {{ key | capitalize }}
                </th>
            </tr>
            </thead>
            <tbody>
                <tr v-for="entry in rows">
                    <td v-for="key in columns">
                    {{entry[key]}}
                    </td>
                </tr>
            </tbody>
        </table>
    </div>
</template>


<script>
export default {
    name:'tableau',
    props: {
        rows: Array,
        columns: Array,
        titre: String
  }
}
</script>

This works.

Then, here is what I would like: being able to put my values from the controller into footballer.blade.php, which is using TableauComponent.vue

FootballerController

public function footballer($id){
    //process to get all this data in DB ($footballer, $gridData, $gridColumns, $title)
$footballer= (Footballer::select(SOME REQUEST)->where('id', '=', $id)->get())[0];

        return view('footballers/footballer', ['footballer' => $footballer,
        'gridData' => $gridData,
        'gridColumns' =>  $gridColumns,
        'title' => $title] );
    }

And in footballer.blade.php

  <tableau
    v-bind:titre="{{ $title }}"
    :rows="{{ $gridData }}"
    :columns="{{ $gridColumns }}" >
  </tableau>

Then in app.js I wouldn't need data anymore

const tableau = new Vue({
    components:{tableau:Tableau
   }
}).$mount('#tableau');

But this doesn't work and tells me "Property or method is not defined on the instance but referenced during render"

I don't manage at all and am worndering is I have the good way of doing: Should I not get my data in FootballerController? If not, where can I get it then?

Thanks a lot in advance.

Upvotes: 1

Views: 6123

Answers (3)

Takachi
Takachi

Reputation: 751

Your are using ':' symbol before your attributes in your blade, which means 'v-bind' as the doc says : VueJS Shorthands. So first, for assigning a String to a props, you don't need ':' before 'titre'.

Then, to solve your problem you could try to add a default value to your props, for example :

props: {
    rows: {
        default: []
    },
    columns: {
        default: []
    },
    titre: {
        default: ''
    }
}

I didn't try but I think it should works.

Upvotes: 2

Maxiss
Maxiss

Reputation: 1056

Thanks a lot, indeed the php array to javascript array was the issue.

In the php controller, I parse my data into json

'gridData' =>json_encode($gridData),

In the php view footballer.blade.php

<tableau
   titre="{{ $title }}"
   rows="{{ $gridData }}">
</tableau>

And in my Vue view, I was getting an array, and changed the code for this:

 rows: {
          type: String,
          default: ""
      }

 var rowsArray = JSON.parse(this.rows)

Now it seems like the data I get after my request isn't properly parsed, but that's another point :)

Upvotes: 0

Cloud Soh Jun Fu
Cloud Soh Jun Fu

Reputation: 1512

When you use {{ value }} in both Blade & javascript framework at the same time. You need to use @{{ value }} to avoid collision between Blade & Vue.

try

<tableau
  v-bind:titre="@{{ $title }}"
  :rows="@{{ $gridData }}"
  :columns="@{{ $gridColumns }}" >
</tableau>

Besides that, when you use :rows="value", the value must be javascript syntax, otherwise when rows="value", the value would be treated as string.

You might need to use json_encode to format your data from the Laravel, or use @json if you're using Laravel 5.5^.

Upvotes: 5

Related Questions