Platform browser dynamic providers not used - javascript

I'm trying to set my LOCALE_ID token before my angular app bootstraps by using the documentation method:
import { LOCALE_ID } from '#angular/core';
import { platformBrowserDynamic } from '#angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
platformBrowserDynamic().bootstrapModule(AppModule, {
providers: [{provide: LOCALE_ID, useValue: 'fr-FR' }]
});
When checking the token in my AppModule's constructor, it seems like it's been reset to defaults
export class AppModule {
constructor(#Inject(LOCALE_ID) private locale: string) {
console.log('Locale - App module', this.locale);
}
}
Outputs: Locale - App module en-US
What am I missing here ?
Here is a Stackblitz reproducing the issue:
https://stackblitz.com/edit/angular-2rdtb6

You should be passing providers to platform injector not to compiler injector:
platformBrowserDynamic([ {provide: LOCALE_ID, useValue: 'fr-FR' }])
\/
extraProviders
.bootstrapModule(AppModule);
Beware that to test it in stackblitz you have to reload application since Angular creates platform only once.
See also:
What you always wanted to know about Angular Dependency Injection tree

You can try just set the provider in app.module.ts
#NgModule({
providers: [
{
// your objects here
}
]
})

Related

how to fix error: inject() must be called from an injection context while using Auth0/angular-jwt?

I am using angular 15.0 and installed #auth0/angular-jwt. the App.Module has configured as follows:
import {HttpClientModule} from "#angular/common/http";
import { JwtModule } from "#auth0/angular-jwt";
export function tokenGetter() {
return localStorage.getItem("jwt");
}
#NgModule({
declarations: [
...
],
imports: [
....
HttpClientModule,
...
JwtModule.forRoot({
config:{
tokenGetter: tokenGetter,
whitelistedDomains: ["localhost:5001"],
blacklistedRoutes: []
}
})
],
providers: [
....
],
exports: [
],
bootstrap: [AppComponent]
})
export class AppModule {
constructor(library: FaIconLibrary) {
library.addIconPacks(far, fab);
}
}
at first, when I imported the JWTModule, I got warnning that: Argument type {config: {tokenGetter: () => string | null, blacklistedRoutes: any[], whitelistedDomains: string[]}} is not assignable to parameter type Routes but no error!. so far, when I run the app, no pages is loaded and in the console this error is rised: NG0203: inject() must be called from an injection context such as a constructor, a factory function, a field initializer, or a function used with EnvironmentInjector#runInContext.I found that this error is only for importing JwtModule and when I remove this, the main page of app is loaded and everything is normal. also, I created an AuthGuard service, I haven't used it yet, Because I assumed that the above error should be resolved first. the snippet code for service is:
import { Injectable } from '#angular/core';
import {ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot} from "#angular/router";
import { JwtHelperService } from '#auth0/angular-jwt';
#Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(private router:Router, private jwtHelper: JwtHelperService){}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
const token = localStorage.getItem("jwt");
if (token && !this.jwtHelper.isTokenExpired(token)){
return true;
}
this.router.navigate(["login"]);
return false;
}
}
Thank you for your guidance on the correct use of the JwtModule of the Auth0/angular-jwt.

can't get ionic v4 CLI generated component to work

I'm currently working with the latest Ionic and I'm having a hard time trying to get a CLI generates component to work.
I start with a blank proyect and then create a new component with:
ionic generate component my-component
The command runs fine and creates the following files:
CREATE src/app/my-component/my-component.component.html (31 bytes)
CREATE src/app/my-component/my-component.component.spec.ts (664 bytes)
CREATE src/app/my-component/my-component.component.ts (293 bytes)
CREATE src/app/my-component/my-component.component.scss (0 bytes)
Then I proceed to use the new component in my main page like this:
<ion-content padding>
<my-component></my-component>
</ion-content>
The app.module.ts file is updated like this:
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { RouterModule, RouteReuseStrategy, Routes } from '#angular/router';
import { IonicModule, IonicRouteStrategy } from '#ionic/angular';
import { SplashScreen } from '#ionic-native/splash-screen/ngx';
import { StatusBar } from '#ionic-native/status-bar/ngx';
import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
import { MyComponentComponent } from './my-component/my-component.component';
#NgModule({
declarations: [AppComponent, MyComponentComponent],
entryComponents: [],
imports: [BrowserModule, IonicModule.forRoot(), AppRoutingModule],
providers: [
StatusBar,
SplashScreen,
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }
],
bootstrap: [AppComponent]
})
export class AppModule {}
When running the app in ionic lab I get the followin error:
ERROR Error: Uncaught (in promise): Error: Template parse errors:
'my-component' is not a known element
This is my system info:
ionic (Ionic CLI) : 4.2.1
Ionic Framework : #ionic/angular 4.0.0-beta.12
#angular-devkit/build-angular : 0.7.5
#angular-devkit/schematics : 0.7.5
#angular/cli : 6.1.5
#ionic/angular-toolkit : 1.0.0
Any ideas why is this happening? I worked before with Ionic 3 and never get this problem.
update:
This is my default my-component.component.ts file:
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-my-component',
templateUrl: './my-component.component.html',
styleUrls: ['./my-component.component.scss']
})
export class MyComponentComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}
In order to use a custom component inside another component you have to include it in exports array.
#NgModule({
....
declarations: [AppComponent, MyComponentComponent],
entryComponents: [],
exports:[MyComponentComponent]
....
})
export class AppModule {}
You can either do this way or you can make all your custom components inside another customModule and then import that module in app.component.ts page.
The name you are referring to the component is wrong. selector for your MyComponentComponent class is app-my-component, so you have to use <app-my-component></app-my-component> instead of <my-component></my-component>.

Very confusing Ionic error - either 2 declarations or none

(I’m from Germany, so I’m sorry if my English is a little messy…)
Hello,
I am trying to create an Ionic-App, which has a register/login function based on this tutorial:
https://devdactic.com/login-ionic-2/
If I copy the code from the shown app.module.ts exactly like this, I’ll always get the error
“No component factory found for LoginPage. Did you add it to
#NgModule.entryComponents?”
when I try to execute the Code (ionic serve or ionic serve -l).
To fix this error, I added the LoginPage to the declarations and entryComponents in the app.module.ts, so my Code looks like this:
import { AuthServiceProvider } from './../providers/auth-service/auth-service';
import { BrowserModule } from '#angular/platform-browser';
import { ErrorHandler, NgModule } from '#angular/core';
import { IonicApp, IonicErrorHandler, IonicModule } from 'ionic-angular';
import { SplashScreen } from '#ionic-native/splash-screen';
import { StatusBar } from '#ionic-native/status-bar';
import { MyApp } from './app.component';
import { LoginPage } from '../pages/login/login';
#NgModule({
declarations: [
MyApp,
LoginPage
],
imports: [
BrowserModule,
IonicModule.forRoot(MyApp)
],
bootstrap: [IonicApp],
entryComponents: [
MyApp,
LoginPage
],
providers: [
StatusBar,
SplashScreen,
{provide: ErrorHandler, useClass: IonicErrorHandler},
AuthServiceProvider
]
})
export class AppModule {}
Now I could open the App, login and visit the “member-area” behind the login and everything seemed to work fine.
But if I try to logout, I get a new error.
“Type LoginPage is part of the declarations of 2 modules: AppModule
and LoginPageModule!”
This message makes sense, because it’s true, that I declared LoginPage twice, so I removed the login.module.ts (because I know that I need the declarations in the app.module.ts apparently).
And this is the confusing point: After I did this, I got another new error, which says
“Component LoginPage is not part of any NgModule or the module has not
been imported to your module”!
Summarized: I may declare “LoginPage” only once – if I do it twice, I’ll get an error. If I remove ONE of them, I’ll get another error, that I declared it nowhere…
And now I am really, really desperate how to solve this problem and how to escape the vicious circle! :-(
If I set the RegisterPage (instead of the LoginPage) as root after logout, this works fine. But if I try to set the RegisterPage as root in the beginning (before login), I’ll get the same issue as at the beginning…
On the internet I found only cases with either the “2 declarations”-error OR the “not part of any”-error, but never both, so I really hope, that someone can help me to solve my problem…
Thank you very much in advance!
Here are some extracts of my Code and error messages:
Screenshot of error no. 1
Screenshot of error no. 2
Screenshot of error no. 3
app.component.ts
import { Component } from '#angular/core';
import { Platform } from 'ionic-angular';
import { StatusBar } from '#ionic-native/status-bar';
import { SplashScreen } from '#ionic-native/splash-screen';
import { RegisterPage } from '../pages/register/register';
#Component({
templateUrl: 'app.html'
})
export class MyApp {
rootPage:any = RegisterPage;
constructor(platform: Platform, statusBar: StatusBar, splashScreen: SplashScreen) {
platform.ready().then(() => {
// Okay, so the platform is ready and our plugins are available.
// Here you can do any higher level native things you might need.
statusBar.styleDefault();
splashScreen.hide();
});
}
}
home.ts
import { Component } from '#angular/core';
import { NavController, IonicPage } from 'ionic-angular';
import { AuthServiceProvider } from '../../providers/auth-service/auth-service';
#IonicPage()
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
username = '';
email = '';
constructor(private navCtrl: NavController, private auth: AuthServiceProvider) {
let info = this.auth.getUserInfo();
this.username = info['username'];
this.email = info['email'];
}
public logout() {
this.auth.logout().subscribe(succ => {
this.navCtrl.setRoot('LoginPage');
// (if I replace 'LoginPage' with 'RegisterPage', it'll work)
});
}
}
Seems that you should move LoginPage out from declarations (as it is declared in module) and add LoginPageModule under imports.
import { LoginPageModule } from '../pages/login/login.module';
#NgModule({
declarations: [
MyApp
],
imports: [
LoginPageModule,
BrowserModule,
IonicModule.forRoot(MyApp)
],
bootstrap: [IonicApp],
entryComponents: [
MyApp
],
providers: [
StatusBar,
SplashScreen,
{
provide: ErrorHandler,
useClass: IonicErrorHandler
},
AuthServiceProvider
]
})

Angular UrlResolver is not overridden by custom provider

I have an Angular application in which I'd like to use a custom UrlResolver provider in order to add some cache breaking logic, as seen in this question (https://stackoverflow.com/a/43289767/868914).
However it doesn't seem that I can override the default compiler UrlResolver using a provider, as I would normally do and as the above link suggests.
Here is a plunker showing what I mean: https://plnkr.co/edit/zFsdyfNIoPcmbLO7WafW?p=preview
If you use the chrome (or other good) dev tools debugger to view the source for compiler.umd.js and search for the UrlResolver and put a break in the 'resolve' method, you can see the default implementation is being used instead of my provided class.
I cannot find a reason for this, hopefully someone on here knows a reason / solution?
Heres app.module code (as seen on the plunkr also)
//our root app component
import {Component, NgModule, VERSION} from '#angular/core';
import {BrowserModule} from '#angular/platform-browser';
import { UrlResolver } from "#angular/compiler";
#Component({
selector: 'my-app',
templateUrl: 'my-app.html',
})
export class App {
name:string;
constructor() {
this.name = `Angular! v${VERSION.full}`
}
}
class NewUrlResolver extends UrlResolver {
resolve(baseUrl: string, url: string): string {
console.log("Custom resolve");
return "rubbish";
}
}
#NgModule({
imports: [ BrowserModule ],
providers: [{
provide: UrlResolver, useClass: NewUrlResolver
}]
declarations: [ App ],
bootstrap: [ App ]
})
export class AppModule {}
You should provide your custom UrlResolver as part of providers in CompilerOptions when bootstraping application:
platformBrowserDynamic().bootstrapModule(AppModule, {
providers: [{ provide: UrlResolver, useClass: NewUrlResolver
}]})
Plunker Example

Angular2 "No provider for Service!" error when provider is added #NgModule

I have an app module and single component application (made to demonstrate my problem), and getting following error:
Error in ./AppComponent class AppComponent_Host - inline template:0:0 caused by: No provider for UserService! ; Zone: <root> ; Task: Promise.then ; Value:
code for AppModule:
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { UserService } from './components/common/userservice';
#NgModule({
imports: [
BrowserModule,
],
declarations: [
AppComponent
],
providers: [UserService],
bootstrap: [AppComponent],
entryComponents: []
})
export class AppModule {
}
Code for my AppComponent:
import { Component} from '#angular/core';
import { UserService} from './userservice';
#Component({
selector: 'App',
template: `<h3>App component</h3>
user name: {{userName}}
`,
providers: []
})
export class AppComponent {
userName: string;
constructor(userService: UserService) {
this.userName = userService.userName;
}
}
My UserService Code:
import { Injectable, EventEmitter } from '#angular/core';
#Injectable()
export class UserService {
obs$: EventEmitter<any> = new EventEmitter<any>()
userName = 'Sherlock Holmes';
}
Now if i add UserService as provider to AppComponent, it will solve the issue. but i dont want to, because i want only one instance of my service in whole application. Even in subModules(feature modules).
according to my understanding, if i add service as provider on module level, then i can just inject it to any component under module.
here is am example i was watching.
Plunker
am using angular2 version: "2.0.0"
The import path is wrong: you use /Common in one and /common right below.
Visual Studio and WebStorm will not show IntelliSense errors for case-sensitivity of paths.
Furthermore, if using Angular 5's AoT template compilation, you can get a "This component is not part of a module" error, even though it is, because the import path is incorrect. Without AoT this will work, so you'll get a surprise when converting to AoT.
Remove your service: UserService from app.module.ts, then add in component:
#Component({
selector: 'App',
template: `<h3>App component</h3>
user name: {{userName}}
`,
providers: [UserService]
})
Hope this will help you.
An additional reason for getting this error - I duplicated a service to a different directory and was updating each file individually. Even though the first file still existed I got this error until I updated app.module.ts.

Categories

Resources