I'm having a problem with Angular Universal, although all guides are different (the official one seems outdated aswell) I've managed to run node.js server with server side rendering.
There's still a huge problem which I can't solve, because I actually have no idea on what's going on
This is the app.module.ts
#NgModule({
declarations: [
AppComponent
],
imports: [
HttpClientModule,
BrowserModule.withServerTransition({
appId: 'ta-un-certificate'
}),
RouterModule.forRoot([{
path: '', loadChildren: './page/page.module#PageModule'
}], {
enableTracing: false,
useHash: false
}),
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: HttpLoaderFactory,
deps: [HttpClient]
}
})
],
providers: [
SeoService,
DataService, {
provide: HTTP_INTERCEPTORS,
useClass: HttpErrorInterceptor,
multi: true
}],
bootstrap: [
AppComponent
]
})
It simply loads another module, PageModule with its components and stuff
#NgModule({
imports: [
CommonModule,
TranslateModule,
RouterModule.forChild([{
path: ':name/:id', component: PageComponent
}, {
path: '', pathMatch: 'full', component: RedirectComponent
}])
],
declarations: [
RedirectComponent,
PageComponent,
BannerComponent,
BodyComponent,
FooterComponent
]
})
export class PageModule {
}
For the server part, I made another module, app.server.module.ts which is the one used by node.js
#NgModule({
imports: [
AppModule,
ServerModule,
ModuleMapLoaderModule,
ServerTransferStateModule
],
providers: [
SeoService
],
bootstrap: [AppComponent],
})
export class AppServerModule {
}
The problem is that if I try to call a route from node.js server, eg. http://localhost:4000/foo/bar, the node.js server console prints out a huge error, starting with this:
Error: Uncaught (in promise): ReferenceError: navigator is not defined
[...]
(it's really huge, if u need something please ask)
And page doesn't get rendered, as from cURL I get only <app-root><router-outlet></router-outlet></app-root> inside html body.
I think I've checked so many guides that I've completely lost the right way to do it, but cloning Angular Universal Starter seems doing what I'm expecting from Universal
Searching on compiled server.js script, the one executed by node, it seemed like there was an error inside Translator. So I focused searching for issues between html rendering and Translation pipe, but then I've just found a navigator.language.split inside a service (app wasn't built by me). Moved that control inside a isPlatformServer block solved my issue.
This was the breaking part of code
private _language = navigator.language.split('-')[0];
constructor(private _http: HttpClient) {
}
Which I edited as following
private _language;
constructor(#Inject(PLATFORM_ID) private platformId,
private _http: HttpClient) {
if (isPlatformServer(this.platformId)) {
this._language = 'en';
} else {
this._language = navigator.language.split('-')[0];
}
}
Fixed the issue
Related
I am trying to create a shared logging module in NestJS that can be shared between multiple micro-services.
The logging module works when it is part of the micro-service but when I extract the code to its own NPM module it no longer works.
Below is a sample of my shared NPM module code:
// my-logger.module.ts
import { Module } from '#nestjs/common';
import { ConfigModule, ConfigService } from '#nestjs/config';
import { LoggerModule } from 'nestjs-pino';
#Module({
imports: [
LoggerModule.forRootAsync({
imports: [ConfigModule],
useFactory: async (configService: ConfigService) => ({
pinoHttp: {
level: process.env.LOG_LEVEL || 'info',
redact: configService.get<string[]>('logger.redacted.fields'),
prettyPrint: {
colorize: false,
singleLine: true,
levelFirst: false,
translateTime: "yyyy-mm-dd'T'HH:MM:ss.l'Z'",
messageFormat: '{req.headers.x-correlation-id} [{context}] {msg}',
ignore: 'pid,hostname,context,req,res,responseTime',
errorLikeObjectKeys: ['err', 'error'],
},
},
}),
inject: [ConfigService],
}),
],
controllers: [],
providers: [],
})
export class MyLoggerModule {}
Below is a sample of the App Module from my NestJS micro-service
// app.module.ts
import { Module } from '#nestjs/common';
import { ConfigModule } from '#nestjs/config';
import configuration from '../config/configuration';
import { MyLoggerModule } from '#my-company/my-logger.module';
import { HttpModule } from '#nestjs/axios';
#Module({
imports: [
ConfigModule.forRoot({ load: [configuration] }),
MyLoggerModule,
HttpModule,
],
controllers: [],
providers: [],
})
export class AppModule {}
The micro-service builds and deploys correctly with the shared npm module. However, each time I send a new request it causes the service to restart with the following error:
node[1]: ../src/tcp_wrap.cc:149:static void node::TCPWrap::New(const v8::FunctionCallbackInfo<v8::Value>&): Assertion `args[0]->IsInt32()' failed.
Does anyone have any ideas on why this is failing ?
Note: I am guessing it has something to do with the ConfigService/ConfigModule being used in both modules. However, I don't understand why the same code works when it is part of the micro-service
We experienced similar issues trying to configure shared modules and ran into a whole host of issues. The root cause was the package versions and that these were not aligned. This answer pointed me in the right direction.
In summary, double check all package version numbers across both applications and shared packages.
I have followed below steps to create Spartacus storefront,
ng new spartacus3
cd spartacus3
ng add #spartacus/schematics --baseUrl https://spartacus-demo.eastus.cloudapp.azure.com:8443/ --baseSite=electronics-spa --ssr
yarn install
yarn start
It installs Angular 10.2.4 and Spartacus 3.1.
It compiles without error.
But am getting blank screen when I'm opening same in browser using URL http://localhost:4200/
I verified network tab in browser it have valid response.
Here is network tab screenshot - screenshot - 1, screenshot 2
But no one elements are getting added in DOM.
Here is elements tab screenshot - elements tab screenshot
But in console I have below info,
spartacus-storefront.js:17341 No component implementation found for the CMS component type 'ProfileTagScriptComponent'.Make sure you implement a component and register it in the mapper .
Console tab screenshot
I followed below link,
https://sap.github.io/spartacus-docs/schematics/#adding-spartacus-core-libraries-and-features-to-your-angular-project
Please help me to get working Spartacus app in my local.
Below is my app.module.ts code,
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { translations, translationChunksConfig } from '#spartacus/assets';
import { B2cStorefrontModule } from '#spartacus/storefront';
import { StoreFinderRootModule } from '#spartacus/storefinder/root';
import { provideConfig } from '#spartacus/core';
import { storeFinderTranslations } from '#spartacus/storefinder/assets';
import { storeFinderTranslationChunksConfig } from '#spartacus/storefinder/assets';
#NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AppRoutingModule,
B2cStorefrontModule.withConfig({
featureModules: {
storeFinder: {
module: () => import('#spartacus/storefinder').then(
(m) => m.StoreFinderModule
),
},
},
backend: {
occ: {
baseUrl: 'https://spartacus-demo.eastus.cloudapp.azure.com:8443',
prefix: '/occ/v2/'
}
},
context: {
currency: ['USD'],
language: ['en'],
},
i18n: {
resources: translations,
chunks: translationChunksConfig,
fallbackLang: 'en'
},
features: {
level: '3.0'
}
}),
StoreFinderRootModule
],
providers: [
provideConfig({
i18n: {
resources: storeFinderTranslations,
chunks: storeFinderTranslationChunksConfig,
},
})],
bootstrap: [AppComponent]
})
export class AppModule { }
Once added below config in app.module, then app works fine,
{
provide: ROUTER_CONFIGURATION,
useValue: {
scrollPositionRestoration: 'enabled',
}
}
This code snip is not required for Spartacus version above/= 3.2 as the app have new structure.
In app.module.ts use this baseUrl link baseUrl: 'https://spartacus-training.eastus.cloudapp.azure.com:8443',
I am following doc to start to use queue. I installed #nestjs/bull, bull, #types/bull dependencies. And here is my app.module.ts:
#Module({
imports: [
ConfigModule.forRoot({
load: [configuration],
}),
BullModule.registerQueue({
name: 'create_checkin',
redis: {
host: 'localhost',
port: 6379,
},
}),
EventModule,
],
})
export class AppModule {}
I imported BullModule in root module. And here is my event.service.ts:
#Injectable()
export class EventService {
constructor(
#InjectQueue('create_checkin') private readonly createCheckinQueue: Queue,
) {
}
}
And when I start server, I got the following error message:
Nest can't resolve dependencies of the EventService
Please make sure that the argument BullQueue_create_checkin at index [0] is available in the EventModule context.
I don't know which step I did wrong. Someone can help me?
Had a similar problem, in my case it was enough to add the BullModule to the exports array in order to successfully run the whole project. Like this:
#Module({
imports: [
BullModule.registerQueue({ ... }),
...
],
...
exports: [
BullModule, // <— this is important!
...
]
})
Then in my service I've been able to inject the queue:
#InjectQueue('print') private queue: Queue<PrintJob>
You have to import bull module inside the module you are trying to setup queue. You can also refer https://medium.com/#shikhar01.cse14/bull-queues-in-nestjs-306c51cb0ec2
Make sure you are placing EventService under providers array in EventModule.
#Module({
providers: [EventService],
controllers :[],
imports: [YOUR_MODULES],
exports: [EventService]
})
export class EventModule {}
Try importing BullModule straight in Event Module - I had the same problem and doing it this way make it work.
#Module({
imports: [
BullModule.registerQueueAsync({
name: 'csv',
useFactory: async (config: ConfigService) => ({
redis: config.get('redis'),
}),
inject: [ConfigService],
}),
],
providers: [
CsvService
],
exports: [CsvService],
})
export class CsvModule {}
I know that it's async method, but maybe you should try.
You can do like below
#Module({
imports: [
ConfigModule.forRoot({
load: [configuration],
}),
EventModule,
],
})
export class AppModule {}
#Module({
imports: [
BullModule.registerQueue({
name: 'create_checkin',
redis: {
host: 'localhost',
port: 6379,
},
}),
],
})
export class EventModule {}
Few days ago everything worked, then I created few more routes and since that moment Angular stopped rendering templates. There is no errors, it navigates URL in browser but no template..
Here is the routing module:
const AppRoutes: Routes = [
{ path: '', component: BlogListComponent },
{ path: ':id', component: BlogDetailComponent },
{ path: 'new', component: BlogAddComponent },
{ path: ':id/edit', component: BlogEditComponent },
{ path: 'register', component: RegisterComponent },
{ path: 'login', component: LoginComponent }
];
#NgModule({
imports: [
CommonModule,
RouterModule.forRoot(AppRoutes)
],
exports: [
RouterModule
],
declarations: []
})
export class RoutingModule { }
App module:
#NgModule({
declarations: [
AppComponent,
HeaderComponent,
BlogDetailComponent,
RegisterComponent,
LoginComponent,
BlogListComponent,
BlogAddComponent,
BlogEditComponent
],
imports: [
BrowserModule,
RoutingModule,
NgbModule.forRoot(),
HttpClientModule,
FormsModule,
ReactiveFormsModule
],
exports: [
RouterModule
],
providers: [RouterModule, AuthService, PostService],
bootstrap: [AppComponent]
})
export class AppModule { }
I believe there is problem with forms. I tried to change this.formBuilder.group to new FormGroup but it doesn't change anything.
I looked everywhere and could not find what I was doing wrong. I am using angular 2 to send a GET request to my node servers api and get information which it displays with databinding in my component called trade. The error occurs on the webbrowser when i try to view my angular app. Both my nodejs app and angular2 app are running on the same server.
Service:
https://hastebin.com/ileqekites.js
Component:
https://hastebin.com/agopopadus.cs
Do you have HttpModule imported into one of your Angular modules?
Here is one of mine as an example:
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { HttpModule } from '#angular/http'; // <- HERE
import { RouterModule } from '#angular/router';
import { AppComponent } from './app.component';
import { WelcomeComponent } from './home/welcome.component';
/* Feature Modules */
import { ProductModule } from './products/product.module';
#NgModule({
imports: [
BrowserModule,
HttpModule, // <- HERE
RouterModule.forRoot([
{ path: 'welcome', component: WelcomeComponent },
{ path: '', redirectTo: 'welcome', pathMatch: 'full' },
{ path: '**', redirectTo: 'welcome', pathMatch: 'full' }
]),
ProductModule
],
declarations: [
AppComponent,
WelcomeComponent
],
bootstrap: [ AppComponent ]
})
export class AppModule { }