Angular UrlResolver is not overridden by custom provider - javascript

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

Related

Platform browser dynamic providers not used

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
}
]
})

Directive declared and exported from core module but not triggering Angular 7

I had created a directive in my Core Module folder and added it to declarations and exported in such module. This module is implemented in App Module (The principal module). I use the directive decorator in my index page (This page is declared in another module Page Module) everything is well I don't receive any error but the logic of the directive is not triggering.
I have tried declaring the directive in the Page Module and its working. Also something very curious if remove the directive from the core module it throws the error Cannot determine the module for class HasfunctionalityDirective which is correct
Directive
import { Directive, ElementRef, Renderer2} from '#angular/core';
#Directive({
selector: '[appHasfunctionality]'
})
export class HasfunctionalityDirective{
constructor(
private elem: ElementRef,
private renderer: Renderer2
) {
this.renderer.setStyle(this.elem.nativeElement, 'color', 'blue');
}
}
Core Module
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { HasfunctionalityDirective } from './directives/hasfunctionality.directive';
#NgModule({
declarations: [
HasfunctionalityDirective
],
imports: [
CommonModule,
],
exports: [
HasfunctionalityDirective
]
})
export class CoreModule { }
App Module
import { NgModule } from '#angular/core';
import { AppComponent } from './app.component';
import { CoreModule } from './core/core.module';
#NgModule({
declarations: [
AppComponent,
],
imports: [
CoreModule,
],
bootstrap: [AppComponent]
})
export class AppModule { }
Index.html
<p appHasfunctionality>
index works!
</p>
In this case the element 'p' should change the color to blue.
As you can see the app module receives all the elements of the core and angular doesn't throw any error but the logic is not triggering.
Found the solution to my problem, I was declaring the module on the top layer (main), instead of that I moved to the pages module because I realize this is the only place is used.
You can only get a refence to the element in afterviewinit. try this
import { Directive, ElementRef, Renderer2, AfterViewInit } from '#angular/core';
#Directive({
selector: '[appHasfunctionality]'
})
export class HasfunctionalityDirective implements AfterViewInit {
constructor(
private elem: ElementRef,
private renderer: Renderer2
) {
}
ngAfterViewInit() {
this.renderer.setStyle(this.elem.nativeElement, 'color', 'blue');
}
}

Angular 7 with adding new component 'the server component' isn't appear in browser when I add a component tag?

It is first time To use Angular Now I'm learning angular 7:
- I create a new custom component in
- |src folder
---| app
----|| server (name of my component)
then I added in app.component.html the name of component
I see in the tutorial show in browser
the server component
even if he add it empty element
I do all steps in
server.component.ts file
import { Component } from '#angular/core';
#Component({
selector:'app-server',
templateUrl: './server.component.html'
})
export class ServerComponent {
}
& app.module.ts file
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { AppComponent } from './app.component';
import { ServerComponent } from './server/server.component';
#NgModule({
declarations: [
AppComponent,
ServerComponent
],
imports: [
BrowserModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Have you define your <app-server></app-server> somewhere?
For instance in the app.component.html
<app-navbar></app-navbar>
<app-server></app-server>
<app-footer></app-footer>
Also you will find an example here : https://angular.io/tutorial/toh-pt1
In your app.component.html add :
<app-server></app-server>
Thus you'll see its HTML.
What you did is in fact kind of import it and make it visible to other components declared in AppModule, but you didnt call it actually.

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
]
})

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