Skip to content
This repository has been archived by the owner on Jan 14, 2020. It is now read-only.

Allow to have getInitialData in non-route components #100

Open
IlyaSemenov opened this issue Jun 14, 2018 · 1 comment
Open

Allow to have getInitialData in non-route components #100

IlyaSemenov opened this issue Jun 14, 2018 · 1 comment

Comments

@IlyaSemenov
Copy link
Contributor

Currently, getInitialData is forcefully disallowed to be present in any component that is not a matched route component.

This is not convenient in real life, as there are situations when I need to render a component with getInitialData not as a root route component.

1. Proxy component

I have a catch-all route:

{ path: '/:path', component: CatchAll }

whose getInitialData dynamically matches context.route.params.path against an external API and decides which child component to render. Example: /all will be a collection component, and /ream will be a product component.

The proxy will then call the specific proxied component's getInitialData, and render it with <component :is="component" ...> (another difficulty here is how to pass that data, I'm currently using a mixin which puts it into this.$initialData and then Ream puts it into data() itself).

However, currently I can't have getInitialData in proxied components at all, Ream will crash with "Error: getInitialData method can only be used in a route component". The workaround is to name it getInitData or something like that, which brings inconsistency.

1a. Proxy component + direct routes to proxied components

Same as above, but I may also have an additional route like /product/:path pointing to the same component (bypassing the catch-all proxy). In that case, the component will need to have getInitialData, but then it will be disallowed when called from a proxy.

2. Preview mode

I may have a Product route component (which uses getInitialData to pull data), and also a ProductPreview or ProductHistory component which acquires product data somehow on its own and then renders the product component with that data. When included from ProductPreview, Product will crash.

Currently there's no simple workaround for 1a and 2 (other than splitting each such component into two).


For starters, I would simply remove that limitation. There is nothing wrong in having getInitialData method in any component, it doesn't harm.

Ideally, I would like to support this: <component :is="routeComponent" $initialData="..."> (or $data="...")

Then setInitialData here:
https://github.com/ream/ream/blob/f3fed25afe50b9bcf2dd9d9bacbba993aa22d675/app/utils.js#L23

may look something like:

    let initialData
    if (vm.$isRouteComponent) {
      initialData = vm.$dataStore.getData(vm.$initialDataKey)
    } else if (vm.$attrs.$initialData) {
      initialData = vm.$attrs.$initialData
    } else {
      // If you insist on throwing an exception
      throw new Error(
        '`getInitialData` method can only be used in a route component'
      )
    }

    vm.$initialData = initialData

Sure thing it's sort of a hack, but then the whole getInitialData is a hack, too.

@IlyaSemenov
Copy link
Contributor Author

IlyaSemenov commented Jul 5, 2018

FYI, I had to end up splitting components into several: "front-end" components that have getInitialData (separate for each route endpoint) but no rendering functions and a single "back-end" component that does the rendering (with the single data property).

This was actually better (in my specific, quite complex case). However, for simpler scenarios I believe the above still makes sense.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant