kamilkisiela / apollo-angular

A fully-featured, production ready caching GraphQL client for Angular and every GraphQL server 🎁
https://apollo-angular.com
MIT License
1.5k stars 309 forks source link

Get an error "Cannot read properties of undefined (reading 'query')" when load the module by module federation #1817

Closed zshlomyz closed 1 week ago

zshlomyz commented 2 years ago

I'm using @angular-architects/module-federation to split the code into micro frontends. I'm using named client in my MFE to support multiple clients. The module (module1) that use Apollo is configured like that:

  imports: [...,
HttpClientModule
    ApolloModule],
  providers:
  [
    {
      provide: APOLLO_NAMED_OPTIONS,
      useFactory: (httpLink: HttpLink) => {
        return {
          client1: {
          cache: new InMemoryCache(),
          link: httpLink.create({
            uri: myUrl,
          }),
        }};
      },
      deps: [HttpLink],
    }
  ]

I'm using the named client on the query like that: query myQuery{ data @namedClient(name: "client1") ..... and use it like that:

this.apollo.watchQuery({
      query: <reference to query....>,
    }).valueChanges.subscribe(res=><handle the data..>)

When I run the MFE by itself, it bootstraped by the app.module of the MFE load module1 and the ApolloModule and it works. When I load module1 using @angular-architects/module-federation, the app.module of the shell is import the ApolloModule but there is an error:

ERROR TypeError: Cannot read properties of undefined (reading 'query')
    at myQueryGQL.fetch (ngApollo.mjs:347:16)
    at MyComponent.ngOnInit (my-component.component.ts:86:43)
    at callHook (core.mjs:2498:22)
    at callHooks (core.mjs:2467:17)
    at executeInitAndCheckHooks (core.mjs:2418:9)
    at refreshView (core.mjs:11992:21)
    at refreshEmbeddedViews (core.mjs:13027:17)
    at refreshView (core.mjs:12001:9)
    at refreshComponent (core.mjs:13073:13)
    at refreshChildComponents (core.mjs:11767:9)`

To Reproduce Steps to reproduce the behavior:

Another try I've also tried to solve it by replacing the myQueryGQL with apollo code like that -

export class MyService {
private apollo: ApolloBase;

    constructor(private apolloProvider: Apollo) {
        this.apollo = this.apolloProvider.use('client1');
    }
getData(...){
this.apollo.watchQuery({
                query: MyDocument,
                variables:{...}
            }).valueChanges.subscribe(res=><handle the data>);
}
}

When I used this syntax it works by making the call trough a component of the MFE but when I make the call at a service at the MFE I got the error:

ERROR TypeError: Cannot read properties of undefined (reading 'watchQuery')
    at MyService.getData (myService.service.ts:39:40)
    at MyComponentComponent.ngOnInit (my-component.component.ts:86:8)
    at callHook (core.mjs:2498:22)
    at callHooks (core.mjs:2467:17)
    at executeInitAndCheckHooks (core.mjs:2418:9)
    at refreshView (core.mjs:11992:21)
    at refreshEmbeddedViews (core.mjs:13027:17)
    at refreshView (core.mjs:12001:9)
    at refreshComponent (core.mjs:13073:13)
    at refreshChildComponents (core.mjs:11767:9)

Environment:

+-- @angular/cli@14.1.3
+-- @angular/core@14.1.3
+-- @apollo/client@3.6.9
+-- apollo-angular@4.0.1
+-- graphql@15.8.0
`-- typescript@4.7.4
zshlomyz commented 1 year ago

Hi, I'm still facing the issue - no way to use the package at a micro frontend application. Can you help, please?

gerardcastell commented 1 year ago

Hi! I am facing the same issue! It seems that the library have no idea about how to share or reuse the instance in the mfe remotes. Hope we could find a solution soon 😞 In the meantime we are looking for an alternative package or just do the post the old way.

PowerKiKi commented 1 week ago

I have no idea what "module federation" means for a library. Is there anything special we should do ? or is it supposed to work magically ? No idea !

And I won't research it either. But I will merge a PR if one you can come up with a solution, and explanation. Until then I close the issue, because this is not something I work on personally.