question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Angular 4 and ApolloModule.forRoot() result not being seen as correctly annotated as an NgModule

See original GitHub issue

I am in the process of migrating my App over to Angular 4 as well as upgrading Apollo from the Angular2Apollo days, and I am almost complete in my progress except for the fact that Angular seems to now choke on the Apollo importation. I get the following error:

Error: Unexpected value '[object Object]' imported by the module 'AppModule'. Please add a @NgModule annotation.

I am using the following setup in my module for imports:

imports: [
    ServerModule,
    AppModule,
    ApolloModule.forRoot(() => client)
],

My client looks like this:

import 'isomorphic-fetch';
import ApolloClient, { createNetworkInterface } from 'apollo-client';
import { Config } from './config.node';

export const client = new ApolloClient({
    networkInterface: createNetworkInterface({
        uri: Config.apiHost
    }),
    ssrMode: true
});

The result, when printed, of ApolloModule.forRoot(() => client) looks fine (it resembles the shape of any other imported module it seems).

I spent a lot of time stepping through the Angular2 compiler and core files, printing out debugging log, but it get very complicated, very quickly.

In Angular core, ReflectionCapabilities.prototype.annotations function finds all the decorator stuff (preferring the tsickle method of class decoration apparently). This is called from Angular compiler, function NgModuleResolver.prototype.resolve. Inside that function is the following call findLast(this._reflector.annotations(type), _isNgModuleMetadata). This basically reaches in, gets the decorators, etc, etc, and then calls _isNgModuleMetadata. That function is the following:

function _isNgModuleMetadata(obj) {
    return obj instanceof NgModule;
}

Well, obj (the annotations pulled from the class) is not an instance of NgModule and so at this point NgModuleResolver.prototype.resolve returns null, and this goes all the way up the chain until it’s handled by some code which claims the object being imported is not correctly annotated with NgModule (the original error at the top of the stack).

I am really unsure of how to proceed here. Perhaps I am missing something? Also, I should note that I am attempting to port my Angular Universal stuff to the new built-in server side rendering so these failures are happening on the Node level as the app attempts to render on the server. I haven’t yet ripped out that code to try and just load this browser-level. This stuff did used to work with Angular Universal however. Also, I am on Angular 4.0.0 which was just released 3 days ago or so.

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:2
  • Comments:5 (1 by maintainers)

github_iconTop GitHub Comments

2reactions
samuelhorwitzcommented, May 14, 2017

Hey so this is just yet another issue regarding the fragile ecosystem of web dev. Angular 4 pulled Angular Universal (which was always sort of beta) into it’s main codebase and the documentation is still very sparse. There appears to be a bug where the decorators used for server-side rendering are just different (in terms of JS reference) and this causes the server-side renderer to choke when it sees third party libraries using Angular. I do not believe that the difference is anything but reference based. However if I’m wrong this fix may introduce more bugs, but so far it hasn’t for me (I’m still dealing with other things now though). It is not an issue with Angular version references in third party libs versus the main application as many Stackoverflow/Github answers might indicate, that is another issue that manifests the same way.

Here is the hacky workaround.

ApolloModule['decorators'][0].type = NgModule;
ApolloModule['decorators'][0].args[0].declarations[0].decorators[0].type = Pipe;

Put that in your server-side app.module above the NgModule declaration and after your imports. Obviously you will need to have NgModule and Pipe imported for the above code to work.

import { NgModule, Pipe } from '@angular/core';

Also, if you are not using Typescript then you can use .decorators rather than ['decorators'] as the verbose accessor is just to get the TS compiler to shut up.

0reactions
kamilkisielacommented, Nov 10, 2017

Fixed in v1.0

Read more comments on GitHub >

github_iconTop Results From Across the Web

Angular 4 and ApolloModule.forRoot() result not being seen ...
I get the following error: Error: Unexpected value '[object Object]' imported by the module 'AppModule'. Please add a @NgModule annotation. I am ...
Read more >
Appears in the NgModule.imports of AppModule, but could not ...
It seems to be a problem with Ivy, from my research. I don't have a lot of experience modifying tsconfig.app.json, which is the...
Read more >
Angular vs. React: Which Is Better for Web Development?
Is Angular vs. React just a matter of personal preference? This article gives an in-depth comparison and analysis of various Angular and React...
Read more >
Launching your app with a root module - Angular
An NgModule describes how the application parts fit together. ... the root module, which must be present for bootstrapping the application on launch....
Read more >
Migration Guide – Angular - GraphQL Code Generator
Migration Guide. ApolloModule is back; File upload requires extract-files library. ApolloModule. The lazy- ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found