Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

server side rendering - any way to get state for non 'top level' components serialized ? #1018

Closed
cameronbraid opened this issue Mar 12, 2018 · 4 comments

Comments

@cameronbraid
Copy link
Contributor

cameronbraid commented Mar 12, 2018

I am rendering components on the server that use <await> to pull in additional data to use when rendering.

One of these components is not a top level component and therefore its state is not serialised to the browser. So when the component is rendered in the browser the first time it has to fetches the data from the server. While fetching, the UI is in a degraded state - showing partial content - infact less content than was shown when it was rendered on the server

I'm not quite sure how to solve this. Getting the component state serialized and re-constructured via require('marko/components').init(); would be a neat solution.

I've tried hacking it into global state, however due to the use of the await tag, the global data is serialised before the components within the <await> tag are resolved

@jasonmacdonald
Copy link
Contributor

Is the await data not being passed as input to another tag? Or is just rendering it in place? It would be helpful if you could show an example :)

@cameronbraid
Copy link
Contributor Author

So are top level components within an <await> tag meant to have their state serialised ?

My await data was being rendered in place, however I can always split the component into two.

This may be a solution, however I think there is still an issue with the <await> tag on in the browser

Uncaught Error: Tried to render async while in sync mode. Note: Client side await is not currently supported in re-renders (Issue: #942).

@cameronbraid
Copy link
Contributor Author

And to provide some context, here is an simple example I setup :

PromiseParentWithWait.marko

class {
  onCreate() {
    this.state = {
      promise : null,
      start : Date.now(),
    }
  }
  onInput(input) {
    this.state.promise = new Promise((resolve, reject)=>{
      setTimeout(()=>resolve({start:this.state.start, end:Date.now()}), 1000)
    })
  }
}
<div.PromiseParentWithWait>
  <await(data from state.promise)>
    <PromiseChildOfWait data=data/>
  </await>
</div>

PromiseChildOfWait.marko

class {
  onMount() {
    debugger
  }
}
<div.PromiseChildOfWait>
  ${input.data.end - input.data.start}
  ${JSON.stringify(input.data)}
</div>

Now, putting issue: #942 aside for now, if you statement that children of <await> components should be serialized, I would expect to see the input data element in the server generated page source, but its not there

<script>(function(){var w=window;w.$components=(w.$components||[]).concat({"w":[["s0",0,{},{"f":1,"s":{"slidenav":false}}]],"t":["/drivenow-frontend$4.0.0-SNAPSHOT/src/components/Page.marko"]})||w.$components})()</script></body></html><!--M/s0-->

@DylanPiercey
Copy link
Contributor

The <await> tag currently is only supported on the server-side. Having said that there is an isomorphic <await> implementation that supports most features except client-reorder (https://gist.github.com/DylanPiercey/9d65759ffa4ff7752a2bc8aa74f5da40). Eventually, we want to have a more holistic solution to this, but it is actually quite a complicated problem that will likely require API changes.

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

No branches or pull requests

3 participants