Angular CLI 6.x environment files for a library - javascript

I've created a library with the new CLI 6.x. I've also created an Angular service inside it and I would like to use different URLs for my dev and prod environment. So I created an environment.ts and an environment.prod.ts file in my library folder.
//dev
export const environment = {
production: false,
url: 'dev-url'
};
//prod
export const environment = {
production: true,
url: 'prod-url'
};
I also added the 'fileReplacements' property to the angular.json file:
"configurations": {
"production": {
"fileReplacements": [{
"replace": "projects/tk-shared/src/environments/environment.ts",
"with": "projects/tk-shared/src/environments/environment.prod.ts"
}],
"project": "projects/tk-shared/ng-package.prod.json"
}
}
Compiling the library with the ng build tk-shared works and uses the dev settings, however when compiling with ng build --prod tk-shared I get the following error:
Schema validation failed with the following errors: Data path "" should NOT have additional properties(fileReplacements).
My tip is that the reason is that tk-shared has the projectType: "library" property in angular.json.
Anyway, is it possible to use environment files in a library?

Thanks, #R. Richards for pointing me to the right solution!
These two sources helped me figure out how to do this injection correctly: LINK1 and LINK2.
So what I did ...
Created an InjectionToken and modified my TkSharedModule:
export const BASE_URL = new InjectionToken<string>('BASE_URL');
//...
export class TkSharedModule {
static forRoot(host: string) {
return {
ngModule: TkSharedModule,
providers: [{
provide: BASE_URL,
useValue: host
}]
}
}
}
Provided a value for this token from the environment files in my AppModule:
import {environment} from '../environments/environment';
//...
#NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
TkSharedModule.forRoot(environment.url)
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
And finally injected this value in my service:
//MyServiceService
import { BASE_URL } from '../tk-shared.module';
constructor(#Inject(BASE_URL) BASE_URL: string) {
console.log('base url', BASE_URL);
}

Related

Reload env variables when k8s configMap changes in Nest.js application

I have a Nest.js based application running in kubernetes. There is ConfigModule initialized in the app and ConfigService that reads env variable defined in configMap.
#Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
}),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
#Injectable()
export class AppService {
#Inject(ConfigService)
private config: ConfigService;
getHello(): string {
const app = this.config.get('app-name')
const psw = this.config.get('app-password')
return `name: ${app}, password: ${psw}`;
}
}
configMap.yaml is attached to my container in deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nestjs-k8s
spec:
selector:
matchLabels:
app: nestjs-k8s
replicas: 1
template:
metadata:
labels:
app: nestjs-k8s
spec:
containers:
- name: nestjs-k8s
image: multiplexor88/nestjs-k8s
ports:
- containerPort: 3000
envFrom:
- configMapRef:
name: config-map
- secretRef:
name: secret
I want to refresh my configuration in application when configMap is changed.
Is there a way to make it?
If it is not possible, then at list is somehow schedule Nest.js ConfigModule to reinitialize without application restart.

NestJs Testing with CACHE_MANAGER injected

I have some service in which I inject the CACHE_MANAGER in the constructor
import { CACHE_MANAGER, Inject, Injectable } from '#nestjs/common';
import { Cache } from 'cache-manager';
...
export class ManagerService {
constructor(#Inject(CACHE_MANAGER) private cacheManager: Cache) {}
...
}
That gives me an error when I test the modules the import those service
Nest can't resolve dependencies of the ManagerService (?). Please make sure that the argument CACHE_MANAGER at index [0] is available in the Web3ManagerService context.
I'm relatively new to NestJs so I really cannot figure out how to solve it
To inject the cache manager provider under the CACHE_MANAGER, you need to import the nestjs module that creates this provider into the module that has the ManagerService
#Module({
imports: [CacheModule.register()], // <<<<
providers: [ManagerService],
})
export class AppModule {}
like the docs shows https://docs.nestjs.com/techniques/caching
I just had the same problem and resolved it this way:
manager.service.spec.ts
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [ManagerService, { provide: CACHE_MANAGER, useValue: {} }],
}).compile();
service = module.get<ManagerService>(ManagerService);
});
Set isGlobal: true:
CacheModule.register({
url: process.env.REDIS_URL,
db: 0,
port: parseInt(process.env.REDIS_PORT),
password: process.env.REDIS_PASSWORD,
isGlobal: true, //<<<<<<<
})

Keycloak - how to disable sharing session between two (Angular) client apps?

I have two angular client applications that use Keycloak's angular client for authentication. The problem is, that when i log in on one of them, i'm automatically being logged to another one. I have separate client for each one though.
Keycloak service initialization looks like this in both apps:
#NgModule({
declarations: [AppComponent],
imports: [
AppRoutingModule,
BrowserModule,
KeycloakAngularModule
],
providers: [KeycloakService],
entryComponents: [AppComponent]
})
export class AppModule implements DoBootstrap {
constructor(private keycloakService: KeycloakService) {
}
ngDoBootstrap(app: ApplicationRef) {
this.keycloakService
.init({config: environment.keycloak, initOptions: {onLoad: 'login-required'}})
.then(() => app.bootstrap(AppComponent));
}
}
Keycloak config for the first app:
const keycloakConfig: KeycloakConfig = {
realm: 'quick',
url: 'http://localhost:8000/auth',
clientId: 'quick-ui-customer'
};
export const environment = {
production: false,
keycloak: keycloakConfig,
};
And for the second one:
const keycloakConfig: KeycloakConfig = {
realm: 'quick',
url: 'http://localhost:8000/auth',
clientId: 'quick-ui-employee'
};
export const environment = {
production: false,
keycloak: keycloakConfig,
};
That is a core feature of Single Sign On protocol. But if you don't want to share session, then create clients in different realms.

Upgrading AngularJS to Angular, AppModule was bootstrapped, but it does not declare "#NgModule.bootstrap" Error

I'm currently experimenting with upgrading an AngularJS app to Angular. Been following along the tutorial on Angular.io. There are a few differences between that project and mine. I'm using RequireJS, Gulp and Webpack.
My index.html asks for requireJS/main.js, main.js starts
The first step I'm trying to get working is to bootstrap a hybrid application with NgUpgrade.
What I've tried so far from google searching is tweak the tsconfig, changing around to different version of zone.js, re-configuring around the order of things loading.
The error that I can't seem to resolve or find any resolutions to on the internet is:
Error: Uncaught (in promise): Error: The module AppModule was bootstrapped, but it does not declare "#NgModule.bootstrap" components nor a "ngDoBootstrap" method. Please define one of these.
Here is my tsconfig.json
{
"compilerOptions": {
"module": "amd",
"moduleResolution": "node",
"sourceMap": true,
"declaration":false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": [ "es2017", "dom" ],
"typeRoots":["node_modules/#types"]
},
"include:":["./src/s/**/*"],
"exclude": [
"node_modules","sandbox","gulp-tasks","dist","3rdparty",".settings"
]
}
Here is my main.js which is just the requirejs config:
require.config({
waitSeconds : 0,
baseUrl: './s/lib',
paths: {
'app': 'app',
'angular': 'angular',
'angular-aria': 'angular-aria.min',
'jquery': 'jquery.min'
"wa-angular": "wa-angular.min",
'ui.router.components': 'routeToComponents',
'reflect-metadata':'Reflect',
'zone.js':'zone.js/dist/zone',
'rxjs':'rxjs',
'#angular/common':'common.umd',
'#angular/compiler':'compiler.umd',
'#angular/core':'core.umd',
'#angular/upgrade':'upgrade/upgrade.umd',
'#angular/upgrade/static':'upgrade/upgrade-static.umd',
'#angular/platform-browser-dynamic':'platform-browser-dynamic.umd',
'#angular/platform-browser':'platform-browser.umd'
},
shim: {
'angular': {'exports': 'angular'}
},
priority: [
'angular'
],
packages: [
],
deps: ['app']
});
Here is my app.js
"use strict";
var $ = window.$;
define(["angular"], function(angular) {
require([
"jquery",
"angular-aria",
"wa-angular-module",
"ui.router.components",
"compiler.umd",
"core.umd",
"platform-browser.umd",
"platform-browser-dynamic.umd",
"upgrade.umd",
"upgrade-static.umd",
"reflect-metadata",
"app.module"
], function() {
require(["angular"], function(angular) {
var app = angular
.module(
"wa-module", [
"ngRoute",
"ngAria",
"ngMessages",
"ui.router",
"ui.router.components",
"ui.bootstrap",
"matchmedia-ng",
])
and finally, app.module.ts
import { NgModule } from "#angular/core";
import { BrowserModule } from "#angular/platform-browser";
import { UpgradeModule } from "#angular/upgrade/static";
import { platformBrowserDynamic } from '#angular/platform-browser-dynamic';
#NgModule({
imports: [BrowserModule, UpgradeModule]
})
export class AppModule {
constructor(private upgrade: UpgradeModule) {}
ngDoBootStrap() {
console.log("ngDoBootStrap running");
this.upgrade.bootstrap(document.body, ["wa"]);
}
}
platformBrowserDynamic().bootstrapModule(AppModule);
Please let me know what additional information you all might need to help me.
Thank you in advance.
Solution: ngDoBootstrap() is the correct way of spelling things.
I wrote it like ngDoBootStrap() and it couldn't resolve.
my bad.
(First time posting, sorry it's not thorough or well-formatted)
Not sure if this applies to the version of Angular at the time of the original post, but in Angular 9/10, it should work if you include a bootstrap list in app.module.ts.
#NgModule({
declarations: [AppComponent],
imports: [BrowserModule, UpgradeModule],
bootstrap: [AppComponent]
})
Replace AppComponent with the appropriate overarching component for your application.
You have to change the code in main.ts file
Replace
platformBrowserDynamic().bootstrapModule(AppModule);
with
const platform = platformBrowserDynamic();
platform.bootstrapModule(AppModule);
it may help to resolve your issue.

Can't resolve all parameters for Storage [duplicate]

I try to use this in my Ionic 2 application :
https://ionicframework.com/docs/v2/storage/
I already run
cordova plugin add cordova-sqlite-storage --save
and
npm install --save #ionic/storage
Successfully.
And when I tried to add Storage in my app.module.ts, I had this error :
Error: Can't resolve all parameters for Storage: (?).
at v (http://localhost:8100/build/polyfills.js:3:4864)
at SyntaxError.BaseError [as constructor] (http://localhost:8100/build/main.js:127193:27)
at new SyntaxError (http://localhost:8100/build/main.js:11660:16)
at CompileMetadataResolver._getDependenciesMetadata (http://localhost:8100/build/main.js:27183:31)
at CompileMetadataResolver._getTypeMetadata (http://localhost:8100/build/main.js:27058:26)
at CompileMetadataResolver._getInjectableMetadata (http://localhost:8100/build/main.js:27046:21)
at CompileMetadataResolver.getProviderMetadata (http://localhost:8100/build/main.js:27288:40)
at http://localhost:8100/build/main.js:27246:49
at Array.forEach (native)
at CompileMetadataResolver._getProvidersMetadata (http://localhost:8100/build/main.js:27213:19)
at CompileMetadataResolver.getNgModuleMetadata (http://localhost:8100/build/main.js:26897:50)
at JitCompiler._loadModules (http://localhost:8100/build/main.js:72991:64)
at JitCompiler._compileModuleAndComponents (http://localhost:8100/build/main.js:72951:52)
at JitCompiler.compileModuleAsync (http://localhost:8100/build/main.js:72917:21)
at PlatformRef_._bootstrapModuleWithZone (http://localhost:8100/build/main.js:52753:25)
I don't understand how I have to do to solve it.
My app.module.ts :
import { Storage } from '#ionic/storage';
...
providers: [
{provide: ErrorHandler, useClass: IonicErrorHandler},
PData,
PBackground,
PTranslate,
Storage
]
...
Since Ionic 2.2.0, it's recommended to use #ionic/storage version 2.0.0. Configuration in app.modules.ts has changed since the previous version. The error occurs if you haven't changed everything in the right way.
In app.modules.ts do following changes:
Remove Storage from providers
Change import statement:
from: import { Storage } from '#ionic/storage';
to: import { IonicStorageModule } from '#ionic/storage';
Add the following to the imports array:
IonicStorageModule.forRoot()
The import array should look like below:
imports: [
IonicModule.forRoot(MyApp),
IonicStorageModule.forRoot()
],
NOTE: Do not make any change in imports of Storage in any other files.
Your app.module.ts should look like,
import { Storage } from '#ionic/storage';
export function provideStorage() {
return new Storage(['sqlite', 'websql', 'indexeddb'], { name: 'database_name' });
}
#NgModule({
declarations: [
],
imports: [
IonicModule.forRoot(MyApp)
],
bootstrap: [IonicApp],
entryComponents: [
],
providers: [
{ provide: Storage, useFactory: provideStorage }, Storage
]
})
You have to use set() and get() methods to store and retrieve data in your pages. Have a look at Ionic 2 Storage Tutorial Blog with example video. Hope this helps

Categories

Resources