Passing data to Vue (or similar)

samharrison7 - 5 months ago

I'm just messing around with using a little Vue.js in a Pyro app and am wondering about passing data to Vue from, for example, the posts module. I appreciate for full blown Vue apps then using an API is the way to go, but for adding a bit of behaviour to, say, a list of posts, then passing data in via Twig works nicely. E.g., something like:

{% set posts = entries('posts').recent().get() %}
<post-listing posts="{{ posts.toJSON() }}"></post-listing>

However, doing this means you're not passing data from relationships; e.g., the author name. I was wondering what people's approaches are to this and if I'm missing any methods that will add related fields to the data, like formatters in the API module?

ryanthompson - 5 months ago

@piterden might have something to say here - but I would try adding .load(['createdBy']) to eager load the relations - idk if it ends up in the JSON though.

API is a no brainer for this though - formatters can join relations. Should be up and running in less than a few minutes using a personal access token (doesn't expire).

piterden - 5 months ago

Suppose you have missed a colon

  <div id="App">
    <app
      :types="{{ types|json_encode }}"
      :menus="{{ menus|json_encode }}"
      :config="{{ config|json_encode }}"
      :events="{{ events|json_encode }}"
      :brands="{{ brands|json_encode }}"
      :banners="{{ banners|json_encode }}"
      :reviews="{{ reviews|json_encode }}"
      :messages="{{ messages|json_encode }}"
      :categories="{{ categories|json_encode }}"
      :fetching="fetching"
    >
    </app>
  </div>

ryanthompson - 5 months ago

You could also add a callback to the PostCollection called maybe vue_data and call it like posts.vueData() and have it return mapped shit for you.

piterden - 5 months ago

    /**
     * Makes an array for vue-app.
     *
     * @return ProductCollection
     */
    public function toVueCollection()
    {
        /* @var ProductInterface $type */
        return $this->model->all()
        ->map(function (ProductInterface $type)
        {
            return [
                'id'   => $type->getId(),
                'name' => $type->getName(),
                'slug' => $type->getSlug(),
            ];
        });
    }

samharrison7 - 5 months ago

Thanks for your responses, some helpful tips there. Just had a look at the API module docs, looks awesome!

Eager loaded stuff doesn't seem to end up in the JSON though, e.g. this doesn't end up with any user or category model data:

PostModel::with('createdBy', 'category')->get()->toJson();

Likewise with PostModel::with('createdBy', 'category')->get()->toJson(); . Any tips? This works with standard Eloquent models.

ryanthompson - 5 months ago

I would add a hook to the controller and take the bull by the horns :-P