I am creating a GraphQL application using NestJs, Fastify, Mercurius with federated service.
I have created two services (User, Restaurant) but when creating the gateway, it only shows the schema of one service and not two.
I tried to inverse the order and it seems that it only takes the one on the top that means when I put User URL first it only takes user schema and the same for the restaurant. Here are a declaration of the gateway and the two service:
Gateway
import { Module } from '#nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { GraphQLModule } from '#nestjs/graphql';
import {
MercuriusGatewayDriver,
MercuriusGatewayDriverConfig,
} from '#nestjs/mercurius';
#Module({
imports: [
GraphQLModule.forRoot<MercuriusGatewayDriverConfig>({
driver: MercuriusGatewayDriver,
gateway: {
services: [
{
name: 'users',
url: 'http://localhost:3001/graphql',
mandatory: true,
},
{
name: 'restaurants',
url: 'http://localhost:3002/graphql',
mandatory: true,
},
],
pollingInterval: 5000,
},
}),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
User
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { UserModule } from '../user/user.module';
import { JwtModule } from '#nestjs/jwt';
import { ConfigModule, ConfigService } from '#nestjs/config';
import { AddressModule } from '../address/address.module';
import { GraphQLModule } from '#nestjs/graphql';
import {
MercuriusFederationDriver,
MercuriusFederationDriverConfig,
} from '#nestjs/mercurius';
#Module({
imports: [
GraphQLModule.forRoot<MercuriusFederationDriverConfig>({
driver: MercuriusFederationDriver,
autoSchemaFile: true,
federationMetadata: true,
}),
UserModule,
AddressModule,
JwtModule.registerAsync({
imports: [ConfigModule],
useFactory: async (configService: ConfigService) => ({
secret: configService.get('SECRET_JWT_ACCESS_KEY'),
}),
inject: [ConfigService],
}),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
restaurant
import { ConfigModule, ConfigService } from '#nestjs/config';
import { JwtModule } from '#nestjs/jwt';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { RestaurantModule } from '../restaurant/restaurant.module';
import { RestauAddressModule } from '../restau-address/restau-address.module';
import { GraphQLModule } from '#nestjs/graphql';
import {
MercuriusFederationDriver,
MercuriusFederationDriverConfig,
} from '#nestjs/mercurius';
#Module({
imports: [
GraphQLModule.forRoot<MercuriusFederationDriverConfig>({
driver: MercuriusFederationDriver,
autoSchemaFile: true,
federationMetadata: true,
}),
JwtModule.registerAsync({
imports: [ConfigModule],
useFactory: async (configService: ConfigService) => ({
secret: configService.get('SECRET_JWT_ACCESS_KEY'),
}),
inject: [ConfigService],
}),
RestaurantModule,
RestauAddressModule,
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
all separately are working fine.
Related
I'm in struggle since few days with e2e testing my NestJS application using GraphQL code first approach and TypeOrm.
I'm trying to create a TestingModule by injecting nestjs GraphQLModule with autoSchemaFile and I'm always getting the error "Schema must contain uniquely named types but contains multiple types named ...".
Here a reproduction of my bug with minimal code:
character.entity.ts:
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
import { ObjectType, Field, ID } from 'type-graphql';
#Entity()
#ObjectType()
export class Character {
#PrimaryGeneratedColumn()
#Field(() => ID)
id: string;
#Column({ unique: true })
#Field()
name: string;
}
character.resolver.ts:
import { Query, Resolver } from '#nestjs/graphql';
import { Character } from './models/character.entity';
import { CharacterService } from './character.service';
#Resolver(() => Character)
export class CharacterResolver {
constructor(private readonly characterService: CharacterService) {}
#Query(() => [Character], { name: 'characters' })
async getCharacters(): Promise<Character[]> {
return this.characterService.findAll();
}
}
character.module.ts:
import { Module } from '#nestjs/common';
import { CharacterResolver } from './character.resolver';
import { CharacterService } from './character.service';
import { TypeOrmModule } from '#nestjs/typeorm';
import { Character } from './models/character.entity';
#Module({
imports: [TypeOrmModule.forFeature([Character])],
providers: [CharacterResolver, CharacterService],
})
export class CharacterModule {}
app.module.ts:
import { Module } from '#nestjs/common';
import { CharacterModule } from './character/character.module';
import { TypeOrmModule } from '#nestjs/typeorm';
import { Connection } from 'typeorm';
import { GraphQLModule } from '#nestjs/graphql';
#Module({
imports: [TypeOrmModule.forRoot(), GraphQLModule.forRoot({ autoSchemaFile: 'schema.gql' }), CharacterModule],
controllers: [],
providers: [],
})
export class AppModule {
constructor(private readonly connection: Connection) {}
}
and finally: character.e2e-spec.ts:
import { INestApplication } from '#nestjs/common';
import { Test, TestingModule } from '#nestjs/testing';
import { TypeOrmModule } from '#nestjs/typeorm';
import { CharacterModule } from '../src/character/character.module';
import { GraphQLModule } from '#nestjs/graphql';
describe('CharacterResolver (e2e)', () => {
let app: INestApplication;
beforeAll(async () => {
const module: TestingModule = await Test.createTestingModule({
imports: [
TypeOrmModule.forRoot(),
GraphQLModule.forRoot({ playground: false, autoSchemaFile: 'schema.gql' }),
CharacterModule,
],
}).compile();
app = module.createNestApplication();
await app.init();
});
it('should create testing module', () => {
expect(1).toBe(1);
});
afterAll(async () => {
await app.close();
});
});
And after running npm run test:e2e:
Schema must contain uniquely named types but contains multiple types named "Character".
at typeMapReducer (../node_modules/graphql/type/schema.js:262:13)
at Array.reduce (<anonymous>)
at new GraphQLSchema (../node_modules/graphql/type/schema.js:145:28)
at Function.generateFromMetadataSync (../node_modules/type-graphql/dist/schema/schema-generator.js:31:24)
at Function.<anonymous> (../node_modules/type-graphql/dist/schema/schema-generator.js:16:33)
at ../node_modules/tslib/tslib.js:110:75
at Object.__awaiter (../node_modules/tslib/tslib.js:106:16)
at Function.generateFromMetadata (../node_modules/type-graphql/dist/schema/schema-generator.js:15:24)
I don't find any other way to create a testing module with graphql code first approach on official doc or while googling... Am I missing something ?
Your ormconfig.json need to look like this:
"entities": [
"src/**/*.entity.js"
],
"migrations": [
"src/migration/*.js"
],
"cli": {
"migrationsDir": "src/migration"
}
I.e you need to specify the entities being in the src, not dist folder. If not TypeGraphQL will generate the schema for each resolver twice. To get the generate and run migration commands to work you would have to setup a different ormconfig.json for your development environment.
Environment
CLI: 6.0.3
Cross-platform modules:6.0.0
Android Runtime:6.0.2
iOS Runtime:6.0.2
Plugin(s):
NativeScript-Angular:8.2.0
Angular:8.2.0
After upgrading to the latest cli and nativescript-angular I get a blank white screen when I start the app which opens the page tab based, but when I try to output something using the component ts file I can get it on the console. The problem is only at the template level (I get a blank page).
this is my app.modules.ts file:
import { NgModule, NO_ERRORS_SCHEMA } from "#angular/core";
import { CoreModule } from "./core/core.module";
import { SharedModule } from "./shared/shared.module";
import { AppRoutingModule } from "./app-routing.module";
import { AppComponent } from "./app.component";
import { NativeScriptCommonModule } from "nativescript-angular/common";
import { TNSImageModule } from 'nativescript-image/angular';
import * as applicationModule from "tns-core-modules/application";
import * as imageModule from "nativescript-image";
declare var GMSServices: any;
if (applicationModule.android) {
applicationModule.on(applicationModule.launchEvent, () => {
console.log('initialize pipeline');
imageModule.initialize();
});
} else {
GMSServices.provideAPIKey("*********");
}
// Uncomment and add to NgModule imports if you need to use two-way binding
// import { NativeScriptFormsModule } from "nativescript-angular/forms";
// Uncomment and add to NgModule imports if you need to use the HttpClient wrapper
// import { NativeScriptHttpClientModule } from "nativescript-angular/http-client";
#NgModule({
bootstrap: [AppComponent],
imports: [NativeScriptCommonModule, CoreModule, SharedModule, TNSImageModule, AppRoutingModule],
declarations: [AppComponent],
providers: [],
schemas: [NO_ERRORS_SCHEMA]
})
/*
Pass your application module to the bootstrapModule function located in main.ts to start your app
*/
export class AppModule {}
this is the app-routing.modules.ts
import { NgModule } from "#angular/core";
import { NativeScriptRouterModule } from "nativescript-angular/router";
//import { hasKey } from "tns-core-modules/application-settings";
import { Routes } from "#angular/router";
//const homePath = (hasKey('skipLoginScreen') ? 'home/tabs':'auth/login');
const routes: Routes = [
{
path: "",
redirectTo: "home",
pathMatch: "full"
},
{
path: "home",
loadChildren: "~/app/home/home.module#HomeModule"
},
{
path: "products",
loadChildren: "~/app/products/products.module#ProductsModule"
},
{
path: "auth",
loadChildren: "~/app/auth/auth.module#AuthModule"
},
{
path: "account",
loadChildren: "~/app/account/account.module#AccountModule"
},
{
path: "cart",
loadChildren: "~/app/cart/cart.module#CartModule"
}
];
#NgModule({
imports: [NativeScriptRouterModule.forRoot(routes, { enableTracing: true } )],
exports: [NativeScriptRouterModule]
})
export class AppRoutingModule {}
this is my home-routing.module.ts:
import { NgModule } from "#angular/core";
import { Routes } from "#angular/router";
import { NativeScriptRouterModule } from "nativescript-angular/router";
import { TabsComponent } from "./tabs.component";
import { HomeComponent } from "./home-tab/home.component";
import { CategoriesComponent } from "./categories-tab/categories.component";
import { InfoComponent } from "./info-tab/info.component";
import { LocationsComponent } from "./locations-tab/locations.component";
import { AccountComponent } from "./account-tab/account.component";
export const COMPONENTS = [TabsComponent, HomeComponent, CategoriesComponent, InfoComponent, LocationsComponent, AccountComponent];
const routes: Routes = [
{
path: "",
redirectTo: "tabs",
pathMatch: "full"
},
{
path: "tabs",
component: TabsComponent,
children: [{ path: "home", component: HomeComponent, outlet: "homeTab" }, { path: "categories", component: CategoriesComponent, outlet: "categoriesTab" }, { path: "info", component: InfoComponent, outlet: "infoTab" }, { path: "locations", component: LocationsComponent, outlet: "locationsTab" }, { path: "account", component: AccountComponent, outlet: "accountTab" }]
}
];
#NgModule({
imports: [NativeScriptRouterModule.forChild(routes)],
exports: [NativeScriptRouterModule]
})
export class HomeRoutingModule {}
this is my home.module.ts:
import { NgModule, NO_ERRORS_SCHEMA } from "#angular/core";
import { HomeRoutingModule, COMPONENTS } from "./home-routing.module";
import { SharedModule } from "../shared/shared.module";
import { PushNotificationsService } from './../core/services/push-notifications.service';
// Uncomment and add to NgModule imports if you need to use two-way binding
// import { NativeScriptFormsModule } from "nativescript-angular/forms";
// Uncomment and add to NgModule imports if you need to use the HttpClient wrapper
// import { NativeScriptHttpClientModule } from "nativescript-angular/http-client";
#NgModule({
imports: [SharedModule, HomeRoutingModule],
providers: [PushNotificationsService],
declarations: [...COMPONENTS],
schemas: [NO_ERRORS_SCHEMA]
})
/*
Pass your application module to the bootstrapModule function located in main.ts to start your app
*/
export class HomeModule {}
this is my tabs.component.ts:
import { Component, OnInit } from "#angular/core";
import { Page } from "tns-core-modules/ui/page";
import { RouterExtensions } from "nativescript-angular/router";
import { DataService } from "../core/services/data.service";
import { ActivatedRoute } from "#angular/router";
#Component({
selector: "tabs",
moduleId: module.id,
templateUrl: "./tabs.component.html"
})
export class TabsComponent implements OnInit {
selectedIndex: number = 4;
constructor(private page: Page, private activeRoute: ActivatedRoute, private dataService: DataService, private routerExt: RouterExtensions) {}
ngOnInit(): void {
this.page.actionBarHidden = true;
this.routerExt.navigate([{ outlets: { homeTab: ["home"], infoTab: ["info"], categoriesTab: ["categories"], accountTab: ["account"], locationsTab: ["locations"] } }], { relativeTo: this.activeRoute });
this.dataService.getActivatedTab().subscribe(index => {
this.selectedIndex = index;
});
}
onTabChanged(args) {
setTimeout(() => {
this.dataService.setActivatedTab(args.newIndex);
}, 30);
}
}
I am having a app.component.html file with button to navigate to another component called HomeComponent
<button (click)="nav()" id="nav">Navigate</button>
<router-outlet></router-outlet>
My app.component.ts file
import { Component } from '#angular/core';
import { RouterModule,Router, Routes } from '#angular/router';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'app';
constructor(private router: Router){
}
nav(){
this.router.navigate(['/home']);
}
}
and my app.module.ts
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { AppComponent } from './app.component';
import { HomeComponent } from './home/home.component';
import { RouterModule, Routes,Router } from '#angular/router';
#NgModule({
declarations: [
AppComponent,
HomeComponent
],
imports: [
BrowserModule,
RouterModule.forRoot([{ path: "", component: AppComponent}]),
RouterModule.forChild([{ path: "home", component: HomeComponent}])
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Here is my spec file app.component.spec.ts
import { TestBed, async, ComponentFixture, fakeAsync, tick,inject } from '#angular/core/testing';
import { By, BrowserModule } from '#angular/platform-browser';
import { AppComponent } from './app.component';
import { HomeComponent } from './home/home.component';
import { DebugElement } from '#angular/core';
import { RouterModule, Routes } from '#angular/router';
import { Router, RouterOutlet } from "#angular/router";
import { FormsModule } from "#angular/forms";
import { RouterTestingModule } from '#angular/router/testing';
import * as br from '#angular/platform-browser';
describe('Component:AppComponent', () => {
let location, router;
let mockRouter
beforeEach(() => {
mockRouter = {
navigate: jasmine.createSpy('navigate')
};
TestBed.configureTestingModule({
imports: [RouterTestingModule.withRoutes([
{ path: 'home', component: HomeComponent }
])],
declarations: [AppComponent, HomeComponent]
});
});
it('should go home', async(() => {
let fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
console.log(mockRouter.navigate);
let component = TestBed.createComponent(AppComponent).componentInstance;
component.nav();
spyOn(component, 'nav');
fixture.detectChanges();
expect(mockRouter.navigate).toHaveBeenCalledWith(['/home']);
}));
});
I am getting the result as
In order to create unit test case for router.navigate you can do something like this:
import { TestBed, async, ComponentFixture, fakeAsync, tick,inject } from '#angular/core/testing';
import { By, BrowserModule } from '#angular/platform-browser';
import { AppComponent } from './app.component';
import { HomeComponent } from './home/home.component';
import { DebugElement } from '#angular/core';
import { RouterModule, Routes } from '#angular/router';
import { Router, RouterOutlet } from "#angular/router";
import { FormsModule } from "#angular/forms";
import { RouterTestingModule } from '#angular/router/testing';
import * as br from '#angular/platform-browser';
describe('Component:AppComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule],
declarations: [AppComponent, HomeComponent]
});
});
it('should go home', async(inject([Router], (router) => {
spyOn(router, 'navigate'); //added a spy on router
let fixture = TestBed.createComponent(AppComponent);
let component = TestBed.createComponent(AppComponent).componentInstance;
component.nav();
expect(router.navigate).toHaveBeenCalled();
expect(router.navigate).toHaveBeenCalledWith(['/home']);
}));
});
You have spied on router but you haven't provided it to the testBed environment. Try adding
providers: [
{ provide: Router, useValue: mockRouter},
],
after declarations.
Also you need not include RouterTestingModule since you are not clicking any links.
References:
https://stackoverflow.com/a/46342813/8558515
Angular 2 Unit Testing - Cannot read property 'root' of undefined
app.component.html
<page-router-outlet></page-router-outlet>
app.component.ts
import 'rxjs/add/operator/let';
import { Component, ViewEncapsulation } from '#angular/core';
import { EchoesState, getSidebarCollapsed$ } from './core/store';
import { Store } from '#ngrx/store';
#Component({
selector: "ns-app",
templateUrl: "app.component.html",
})
export class AppComponent {
constructor(private store: Store<EchoesState>){}
}
app.module.ts
import 'nativescript-localstorage';
import { NgModule, NO_ERRORS_SCHEMA } from "#angular/core";
import { NativeScriptModule } from "nativescript-angular/nativescript.module";
import { NativeScriptRouterModule } from "nativescript-angular/router";
import { NativeScriptFormsModule } from "nativescript-angular/forms";
import { AppRoutingModule } from "./app.routing";
import { AppComponent } from "./app.component";
import { ItemService } from "./item/item.service";
import { ItemsComponent } from "./item/items.component";
import { ItemDetailComponent } from "./item/item-detail.component";
#NgModule({
bootstrap: [
AppComponent
],
imports: [
NativeScriptModule,
AppRoutingModule
],
declarations: [
AppComponent,
ItemsComponent,
ItemDetailComponent
],
providers: [
ItemService
],
schemas: [
NO_ERRORS_SCHEMA
]
})
export class AppModule { }
app.routing.ts
import { NgModule } from "#angular/core";
import { NativeScriptRouterModule } from "nativescript-angular/router";
import { Routes } from "#angular/router";
import { ItemsComponent } from "./item/items.component";
import { ItemDetailComponent } from "./item/item-detail.component";
const routes: Routes = [
{ path: "", redirectTo: "/items", pathMatch: "full" },
{ path: "items", component: ItemsComponent },
{ path: "item/:id", component: ItemDetailComponent },
];
#NgModule({
imports: [NativeScriptRouterModule.forRoot(routes)],
exports: [NativeScriptRouterModule]
})
export class AppRoutingModule { }
main.aot.ts
import { platformNativeScript } from "nativescript-angular/platform-static";
import { AppModuleNgFactory } from "./app.module.ngfactory";
platformNativeScript().bootstrapModuleFactory(AppModuleNgFactory);
main.ts
import { platformNativeScriptDynamic } from "nativescript-angular/platform";
import { AppModule } from "./app.module";
platformNativeScriptDynamic().bootstrapModule(AppModule);
package.json
{
"android": {
"v8Flags": "--expose_gc"
},
"main": "main.js",
"name": "tns-template-hello-world-ng",
"version": "3.0.0"
}
store/index.js:
import { Observable } from 'rxjs/Observable';
import { NgModule } from '#angular/core';
import { StoreModule, combineReducers } from '#ngrx/store';
import { compose } from '#ngrx/core/compose';
import { StoreDevtoolsModule } from '#ngrx/store-devtools';
import { localStorageSync } from 'ngrx-store-localstorage';
import 'rxjs/add/operator/let';
import { environment } from '../../environments/environment';
import { getSidebarExpanded } from './app-layout';
import { getAppReducersRegistry, EchoesState, EchoesReducers, EchoesActions } from './reducers';
export { EchoesState } from './reducers';
const actions = EchoesActions; // storeAssets.actions;
const reducers = EchoesReducers; // storeAssets.reducers;
const composeStore = reducers;
const optionalImports = [];
const productionReducer = compose(localStorageSync(Object.keys(reducers), true), combineReducers)(reducers);
export function appReducer(state: any, action: any) {
return productionReducer(state, action);
}
if (!environment.production) { optionalImports.push(StoreDevtoolsModule.instrumentOnlyWithExtension());
}
#NgModule({
imports: [
StoreModule.provideStore(appReducer),
...optionalImports
],
declarations: [],
exports: [],
providers: [ ...actions ]
})
export class CoreStoreModule {
constructor() {
console.log('CoreStoreModule initiated:', reducers);
}
};
function getAppLayoutState(state$: Observable<EchoesState>) {
return state$.select(state => state.appLayout);
}
export function getSidebarCollapsed$(state$: Observable<EchoesState>) {
return state$.select((state) => state.appLayout.sidebarExpanded);
}
store/reducers.ts
import { AppLayout, AppLayoutActions, appLayout, appLayoutRegister } from './app-layout';
import { NowChannellistActions, NowChannellistInterface, nowChannellist, nowChannellistRegister } from './now-channellist';
import { NowPlaylistActions, NowPlaylistInterface, nowPlaylist, nowPlaylistRegister } from './now-playlist';
// reducers
import { PlayerActions, YoutubePlayerState, player, playerRegister } from './youtube-player';
import { UploadsList, VideosListActions, search, searchRegister } from './uploads-list';
import { UserProfileActions, UserProfileData, user, userRegister } from './user-profile';
import { Observable } from 'rxjs/Observable';
export interface EchoesState {
player: YoutubePlayerState;
nowPlaylist: NowPlaylistInterface;
nowChannellist: NowChannellistInterface;
user: UserProfileData;
search: UploadsList;
appLayout: AppLayout;
};
export let EchoesReducers = {
player,
nowPlaylist,
nowChannellist,
user,
search,
appLayout,
};
export let EchoesActions = [
PlayerActions,
NowPlaylistActions,
NowChannellistActions,
UserProfileActions,
VideosListActions,
AppLayoutActions
];
export function getAppReducersRegistry() {
return [
playerRegister,
nowPlaylistRegister,
nowChannellistRegister,
userRegister,
searchRegister,
appLayoutRegister
];
};
export function getPlayer$ (state$: Observable<EchoesState>): Observable<YoutubePlayerState> {
return state$.select(state => state.player);
};
export function getPlayerSearch$ (state$: Observable<EchoesState>): Observable<UploadsList> {
return state$.select(state => state.search);
};
export function getPlayerSearchResults$ (state$: Observable<EchoesState>): Observable<any[]> {
return state$.select(state => state.search.results);
};
export function getAppLayout$ ($state: Observable<EchoesState>): Observable<AppLayout> {
return $state.select(state => state.appLayout);
};
export function getNowPlaylist$ ($state: Observable<EchoesState>): Observable<NowPlaylistInterface> {
return $state.select(state => state.nowPlaylist);
};
export function getNowChannellist$ ($state: Observable<EchoesState>): Observable<NowChannellistInterface> {
return $state.select(state => state.nowChannellist);
};
The error I am getting is:
No provider for Store!
Error
at injectionError (file:///data/data/org.nativescript.MyApptarchec/files/app/tns_modules/#angular/core/bundles/core.umd.js:1238:86)
[angular]
at noProviderError (file:///data/data/org.nativescript.MyApptarchec/files/app/tns_modules/#angular/core/bundles/core.umd.js:1276:12)
[angular]
at ReflectiveInjector_._throwOrNull (file:///data/data/org.nativescript.MyApptarchec/files/app/tns_modules/#angular/core/bundles/core.umd.js:2777:19)
[angular]
at ReflectiveInjector_._getByKeyDefault (file:///data/data/org.nativescript.MyApptarchec/files/app/tns_modules/#angular/core/bundles/core.umd.js:2816:25)
[angular]
at ReflectiveInjector_._getByKey (file:///data/data/org.nativescript.MyApptarchec/files/app/tns_modules/#angular/core/bundles/core.umd.js:2748:25)
[angular]
at ReflectiveInjector_.get (file:///data/data/org.nativescript.MyApptarchec/files/app/tns_modules/#angular/core/bundles/core.umd.js:2617:21)
[angular]
at AppModuleInjector.NgModuleInjector.get (file:///data/data/org.nativescript.MyApptarchec/files/app/tns_modules/#angular/core/bundles/core.umd.js:3585:52)
[angular]
at resolveDep (file:///data/data/org.nativescript.MyApptarchec/files/app/tns_modules/#angular/core/bundles/core.umd.js:11046:45)
[angular]
at createClass (file:///data/data/org.nativescript.MyApptarchec/files/app/tns_modules/#angular/core/bundles/core.umd.js:10899:35)
[angular]
at createDirectiveInstance (file:///data/data/org.nativescript.MyApptarchec/files/app/tns_modules/#angular/core/bundles/core.umd.js:10730:37)
[angular]
at createViewNodes (file:///data/data/org.nativescript.MyApptarchec/files/app/tns_modules/#angular/core/bundles/core.umd.js:12093:49)
[angular]
at createRootView (file:///data/data/org.nativescript.MyApptarchec/files/app/tns_modules/#angular/core/bundles/core.umd.js:11998:5)
[angular]
at callWithDebugContext (file:///data/data/org.nativescript.MyApptarchec/files/app/tns_modules/#angular/core/bundles/core.umd.js:13213:42)
[angular]
at Object.debugCreateRootView [as createRootView] (file:///data/data/org.nativescript.MyApptarchec/files/app/tns_modules/#angular/core/bundles/core.umd.js:12673:12)
[angular]
I know this question seems dead, but for info, the provideStore function doesn't exist anymore, you should do
StoreModule.forRoot(/*your reducers here*/)
You need to add the provider to the NgModule, i.e module.ts under providers,
providers: [
Store
]
You should import Store in your main module (app.module.ts):
imports: [
StoreModule.provideStore({ /* your reducers here... */ }),
...
I'm trying to use the isBrowser function in angular universal but I keep getting the same error when I build. I did install the npm package of angular-universal
npm i angular2-universal --save
'ng build -prod -aot'
ERROR in Illegal state: symbol without members expected, but got {"filePath":"C:/dir/universal/website/node_modules/#angular/platform-browser/platform-browser.d.ts","name":"__platform_browser_private__","members":["BROWSER_SANITIZATION_PROVIDERS"]}.
ERROR in ./src/main.ts
Module not found: Error: Can't resolve './$$_gendir/app/app.module.ngfactory' in 'C:/dir/universal/website\src'
# ./src/main.ts 4:0-74
# multi ./src/main.ts
this is my app.module.ts:
//modules
import { HomeModule } from './home/home.module';
import { IntakeFormulierModule } from './intake-formulier/intake-formulier.module';
import { BrowserModule } from '#angular/platform-browser';
import { UniversalModule } from 'angular2-universal/browser';
import { NgModule } from '#angular/core';
//routing
import { routing } from "./app.routing";
//pages
import { AppComponent } from './app.component';
//isbrowser
import { isBrowser } from 'angular2-universal';
#NgModule({
declarations: [
AppComponent,
],
imports: [
BrowserModule.withServerTransition({
appId: 'website-u - (starter)'
}),
HomeModule,
IntakeFormulierModule,
routing,
],
providers: [
{ provide: 'isBrowser', useValue: isBrowser }
],
bootstrap: [AppComponent]
})
export class AppModule { }
this is my app/home/landing/landing.ts
import { Component, Inject } from '#angular/core';
import { Router } from '#angular/router';
#Component({
...
})
export class LandingComponent {
constructor(//public updateTop: TopImageUpdateService,
public router: Router,
#Inject('isBrowser') public isBrowser: boolean) {}
navigateToResults(name) {
if (this.isBrowser) {
let scrollToTop = window.setInterval(() => {
let pos = window.pageYOffset;
if (pos > 0) {
window.scrollTo(0, pos - 10); // how far to scroll on each step
} else {
window.clearInterval(scrollToTop);
this.router.navigate(['home/page', name]);
}
}, 9)
}
}
}
It looks like they are using isPlatformBrowser() instead of isBrowser() in the angular universal example.
https://github.com/angular/universal#universal-gotchas
import { Component, Inject, PLATFORM_ID, OnInit } from '#angular/core';
import { isPlatformBrowser, isPlatformServer } from '#angular/common';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent implements {
constructor(
#Inject(PLATFORM_ID) private platformId: Object
){
}
ngOnInit(){
if (isPlatformBrowser(this.platformId)) {
//Client only code.
} else {
//Server only code.
}
}
}