josemarluedke / glimmer-apollo

Ember and Glimmer integration for Apollo Client.
https://glimmer-apollo.com
MIT License
39 stars 15 forks source link

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

Open lifeart opened 3 years ago

lifeart commented 3 years ago

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

Given:

Problem:

Solution:

Request:

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 commented 3 years ago

right now I'm getting image

lifeart commented 3 years ago

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 commented 3 years ago

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 commented 3 years ago

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?