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

Feature proposal: server { } in component definition #976

Closed
sirceljm opened this issue Jan 23, 2018 · 2 comments
Closed

Feature proposal: server { } in component definition #976

sirceljm opened this issue Jan 23, 2018 · 2 comments
Labels
status:needs review Needs to be followed up on type:feature A feature request

Comments

@sirceljm
Copy link

sirceljm commented Jan 23, 2018

New Feature

Description

Enable server and server-static tag in .marko component definition. Similar as class & static but they only run on the server side.

Why

This enables to request database services, use aws sdk or other services directly and provide prerendered server output without leaking the implementation details.

Possible Implementation & Open Questions

I already did the initial implementation here: master...sirceljm:server-tag. It is working and right now it is good enough for my needs (apart from the await error) but It would probably need some refinement and discussion.

My .marko component looks something like this now:

static {
    let exportsJSON;

    function importExports(component){
        return component.getEl().dataset.exports;
    }

    let state = {
        myVar: null
    }
}

server-static {
    const runGraphQL = require('src/services/graphql'); // load static libraries here
}

server {
    // run data query
    let postsPromise = new Promise((resolve, reject) => {
         runGraphQL(
             `query P{
               Posts {
                 postId
                 text
                 author
                 date
               }
             }`, function(err, result){
                 if(err) {
                     console.log(err);
                     resolve({
                         error: err
                     });
                 }
                 resolve(result.data.Profile);
             }
         );
    });

    state.myVar = "myVar";
    exportsJSON = JSON.stringify(state);
}

class {
    onCreate() { // happens on server
        this.state = state;
    }

    onMount() { // happens on client
        this.state = JSON.parse(this.el.getAttribute("data-exports"));
    }
}

<div id:scoped data-exports=(exportsJSON ? exportsJSON : importExports(component))> <!-- data-exports <- import data from server rendered component -->
    <await(posts from postsPromise)>
        <for(post in posts)>
            <div>${post.text}</div>
        </for>
    </await>

    ${state.myVar}
</div>

style.sass {

}

style {

}

The catch is that you pass the state from server side to the client side in data-exports attribute
(I hope the other parts are self explanatory enough)

Is this something you're interested in working on?

I am interested in implementing this feature.

Challenges

Right now I am having problems with the await tag. It produces the "Not allowed error" on the client side.
I saw there is an open issue: #942 and that the team is working on it. I hope it gets resolved fast but in the meantime I was thinking on having a feature like no-update on the await tag. if that is not the option then I suppose the component would have to wait for server promise to resolve and then include it into exportsJSON so the resolved promise would be then loaded into client state.

Any feedback is very welcome.

@cameronbraid
Copy link
Contributor

cameronbraid commented Jan 24, 2018

I like the look of where this is going.

One nice addition would be a custom component that abstracts the data-exports

i.e. something that could use like this

class {
  onCrate() {
    this.state = {data:null}
  } 
  onData(data) {
    this.state.data = data
  }
}
<ServerData on-data('onData')/>

or better still when #656 is resolved, something like :

<ServerData | (data)>
  ${data}
</ServerData>

@jasonmacdonald jasonmacdonald added type:feature A feature request status:needs review Needs to be followed up on labels Mar 7, 2018
@DylanPiercey
Copy link
Contributor

This is superseded by Marko 6's tags api.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status:needs review Needs to be followed up on type:feature A feature request
Projects
None yet
Development

No branches or pull requests

4 participants