1

I was playing around a little bit with Vue.js (v.2.0.1). I created a very simple api using Laravel 5.3 in the backend:

In my routes file

Route::get('/', function () {
    $tasks = Task::where('id', '<', 11)->get();

    return view('welcome', [
        'tasks' => $tasks,
});

The tasks table consists of 10 entries with the following structure

table
-------------------------------------------------
- id //a number
- body // a fake short paragraph
- timestamps // created_at, updated_at, etc....

In my js files, I initialize the following View-Model:

var vm = new Vue({
    el: '#my-app',
    data: data,
});

and I am using two custom components as follows:

Vue.component('todo-item', {
    template: '<li>{{ todo.body }}</li>',
    props: ['todo']
});

Vue.component('todo-items', {
    template: '<ul><li v-for="todo in todos">{{ todo.body }}</li</ul>',
    props: ['todos']
});

In welcome.blade.php view file I use the two components above as follows:

<div id="my-app">
    <h1>todo-item</h1>
    <ul>
        <todo-item v-for="todo in {{$tasks}}" :todo="todo"></todo-item>
    </ul>

    <h1>todo-items</h1>
    <todo-items :todos="{{$tasks}}"></todo-items>
</div>

Now, the problem:

If I run the code above (that is passing 10 articles to my view) in my browser I get the following error regarding the <todo-item> component:

- invalid expression: v-for="todo in [{"id":1,"body":"Magnam a sequi tempore dolore. Sapien...... /* a long string */ .....,"updated_at":"2016-09-30 14:42:54"}]

However, when I decrease the number of tasks I fetch and pass to the view in my routes file, lets say to 5 the view is rendered without errors in the browser.

So, what I am asking is * why i get the "invalid expression" error when the length of the binding expression is changing*, (for example is something like a "maximum number of characters" that is allowed to be used as a binding expression in v-for directive...?).

A final note: the <todo-items> component (where the v-for directive its actually part of its template) is rendered without problem even if I select to pass all the $task from my route files

EDIT1: This is a working JSFiddle that reproduces the problem: https://jsfiddle.net/y8z5ojot/

EDIT2 Apparently it seems that the problem occurs due to the existence of Javascript keyword "in" inside of the body of one of the tasks (a possible bug in Vue 2.0.1 which we expect to be solved in a next patch release). I have opened an issue in Vue's github in case someone is interested in tracking the problem.

ira
  • 5,569
  • 6
  • 30
  • 41
  • This isn't an answer to your question, but if you're using a component based approach, you might be better off having a `` component that has its own `` components. You could pass `$tasks` in a as prop to the `` like: `` and coerce it to be JSON (check out prop coercing — only available in Vue 1.0.x). I can show you an example, but I don't want to take away from what you're actually asking here. – tptcat Oct 02 '16 at 15:34
  • @tptcat it would be nice if you could share a JSBin/JSFiddle with an example of the component based approach you suggesting. Regarding the original question, what I am really asking is why I get this Invalid expression error when changing the length of the binding expression in `v-for` directive, so I updated my OP accordingly. Feel free to make any corrections – ira Oct 03 '16 at 09:38

2 Answers2

0

There's a browser limit on attribute size, which you should never come close to hitting in normal situations.

You shouldn't have those tasks in the templates like that anyway, though. They're inaccessible everywhere else in your code. What's in your components data? That's where tasks should be originating from in one way or another.

Bill Criswell
  • 32,161
  • 7
  • 75
  • 66
  • I use `props` to pass the server data to my component. I do not use a data property in my component. However, even If I initialize the data in my component like `data: function () { return { tasks: "" } }` I do experience exactly the same problem – ira Oct 02 '16 at 14:27
  • I'm suggesting `tasks: {{ $tasks }}` essentially, then you pass `tasks` like `:todos="tasks"`. – Bill Criswell Oct 02 '16 at 14:37
  • You are not allowed to use latavels blade syntax `{{$tasks}}` if you are loading your vue code from an external js file like I do (i.e. ` – ira Oct 02 '16 at 15:11
  • Then it looks like you'd need to use an ajax request for the data. Your data originating from inside the templates is just a bad approach. – Bill Criswell Oct 02 '16 at 17:21
  • please have a look in the following post. HTML5 does NOT set a limit for the length of html attributes. http://stackoverflow.com/questions/1496096/is-there-a-limit-to-the-length-of-html-attributes – ira Oct 03 '16 at 21:54
  • I don't even understand your code works at all since you have `"` nested in attributes quoted with `"`. Though, you really should not have data in your templates like that no matter what. – Bill Criswell Oct 04 '16 at 20:13
0

Apparently it seems that the problem occurs due to the existence of Javascript keyword "in" inside of the body of one of the tasks (a possible bug in Vue 2.0.1 which we expect to be solved in a next patch release). I have opened an issue in Vue's github here in case someone is interested in tracking the problem

ira
  • 5,569
  • 6
  • 30
  • 41