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

way to use useQuery on pojo objects (outside of glimmer environment) #48

Open
lifeart opened this issue Oct 19, 2021 · 4 comments
Open

Comments

@lifeart
Copy link
Contributor

lifeart commented Oct 19, 2021

And it's partially solves problem I'm facing:

Given:

  • Glimmer application with async-loaded data
  • SSR should work for this application

Problem:

  • @glimmer/ssr does not support async logic inside renderToString function

Solution:

  • use Vue - like approach - have independend "async" logic, incapsulated in router
  • provide router as DI for glimmer application

Request:

  • I would like to use useQuery inside "model" hook of router (without glimmer/ember application, because it will be attached later)

Usecase example:

import { RouteParams, Router, Page } from '@lifeart/tiny-router';
import { renderToString } from '@glimmerx/ssr';
import { useQuery } from 'glimmer-apollo';
import { IListOfRepositoriesQuery, ListOfRepositoriesQuery } from './components/RepositoriesLoader';
import Component, { hbs, tracked } from '@glimmerx/component';
import { service } from '@glimmerx/service';

export const router = new Router({
  main: '',
});

router.addResolver('main', async (params: RouteParams) => {
    const result = useQuery<IListOfRepositoriesQuery>(router, () => [
         ListOfRepositoriesQuery,
         {
             variables: { login: params.login ?? 'lifeart' },
         }
     ]);  
    await result.promise;
    return result;
});

export async function render(url: string) {
    await router.mount(url, true);
    return renderToString(App, {
        rehydrate: true,
        services: {
            router
        },
    });
}


class App extends Component<{}> {
    constructor(owner: any, args: Record<string, unknown>) {
        // @ts-ignore
        super(owner, args);
        this.router.addHandler((page, data) => {
            this.page = page;
            this.model = data;
        });
    }
    @tracked page!: Page;
    @tracked model!: any;
    @service router!: Router;

    get RouteComponent() {
        return this?.model?.component ?? hbs`<h1>Hello, world</h1>`;
    }

    static template = hbs`
            <this.RouteComponent @model={{this.model}} />
    `;
}
@lifeart
Copy link
Contributor Author

lifeart commented Oct 19, 2021

right now I'm getting
image

@lifeart
Copy link
Contributor Author

lifeart commented Oct 19, 2021

it will be great to have kinda defaultContext, to get things working, and defaultContext may resolve syntheticOwner.

to prevent memory leaks, setClient may return destructor to call it manually in proper place

@lifeart
Copy link
Contributor Author

lifeart commented Oct 19, 2021

once i'm trying to manually create owner, I see:

Unable to find owner from the given context in glimmer-apollo setClient

import { setOwner }  from '@glimmer/owner';

const owner = {};
import setupApolloClient from './configs/apollo';

export const router = new Router({
  main: '',
  second: '/second'
});

setOwner(router, owner);
setupApolloClient(router);

@lifeart
Copy link
Contributor Author

lifeart commented Oct 19, 2021

lol, it started working, once I'm deduplicated @glimmer/owner packages, wondering, could we export appollo's environment into appication? to avoid package duplication issue?

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

1 participant