Using component from parent module inside of child modules - javascript

In my Angular project, I am trying to use a component from a shared module where its child component is imported in the Dashboard module but facing this error.
If app-send-email is an Angular component, then verify that it is part of this module.
If 'app-send-email' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '#NgModule.schemas' of this component to suppress this message.
app.routing.ts
const routes = [
{
path: 'dashboard',
loadChildren: () => import('./dashboard/dashboard.module').then(m => m.DashboardModule)
}]
dashboard.module.ts
import { SendEmailComponent } from './shared/send-email.component';
import { SharedDialogComponentModule } from '../shared/shared-dialog-component.module';
#NgModule({
imports: [SharedDialogComponentModule],
declarations: [ RecruiterSendEmailComponent ]
});
shared-dialog-component.module.ts
import { EmailDialogComponent } from '../../dashboard/shared/template/dialog/email-dialog/email-dialog.component';
#NgModule({
declarations: [EmailDialogComponent],
entryComponents: [EmailDialogComponent],
exports: [EmailDialogComponent]
})
email-dialog.component.html
<app-send-email></app-send-email>
Can anyone please help with this issue?

Well, you need to import the module SharedDialogComponentModule
import { SendEmailComponent } from './shared/send-email.component';
import { SharedDialogComponentModule } from '../shared/shared-dialog-component.module';
#NgModule({
import: [ SharedDialogComponentModule ]
declarations: [ RecruiterSendEmailComponent ]
});

Related

Angular Routing not working with different components

I have two components. Component A and Component B. I want to create a navigation system in component A that on click will load the appropriate element in component B.
I know within the same component we can use routerLink and router-outlet. But how can i achieve the same in my case ??
for example:
Component A
<a routerLink="/userHome"></a>
Component B
<router-outlet></router-outlet>
And my routing module is :
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import {RouterModule, Routes} from '#angular/router';
import {UserHomeMainBodyComponent} from './components/user-home-
main-body/user-home-main-body.component';
import {UserNotificationsBodyComponent} from './components/user-
notifications-body/user-notifications-body.component';
const routes: Routes = [
{ path: 'userHome', component: UserHomeMainBodyComponent},
{path: 'userNotifications', component:UserNotificationsBodyComponent}
];
#NgModule({
declarations: [],
imports: [
CommonModule,
RouterModule.forRoot(routes)
],
exports: [RouterModule]
})
export class AppRoutingModule { }

Looking for pointers on routing between feature modules in angular

I was working on a big project of mine in angular, discovered feature modules and routing modules, then tried to implement that in order to better organize the project. When I did this, the app became very disfunctional. Since then, i made this test project to try to implement routing between feature modules, on a smaller, more managable scale.
This test project works, but there are some small problems that I know will cause issues down the line, and id like to resolve.
There are two big problems as I see it:
<a routerLink="some/link> does not work in feature modules, only app module: it renders in the markup as plaintext with no working link. I tried importing routerLink to the feature modules module.ts file, as a last ditch effort, but still nothing.
I was hoping that routing to a feature module, if configured that way, could display different mark up and styling, for example- routing to module-a shows one navigation menu, and routing to module-b shows another. Instead, the default behaivor happens- app.component is displayed everywhere, and routing
to a feature module makes the url specified component appear in place of router-outlet. Id like to disable this default behaivor if possible, so that components routed to in one feature module have one set of styles and features, and components routed to in another module have different styling and features- as if router-outlet recognizes that feature-a/component is part of feature-a, and in turn loads that modules' html and css as the app.component instead of the root app.component.
Attached the source code below, for this test project. I only included source for module feature-a, as feature-b is in essence the same thing with different text, to prevent unneeded cluttering
app.module.ts
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { FeatureAModule } from './feature-a/feature-a.module';
import { FeatureBModule } from './feature-b/feature-b.module';
#NgModule({
declarations: [
AppComponent,
],
imports: [
BrowserModule,
AppRoutingModule,
FeatureAModule,
FeatureBModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
App.routing.ts
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { ChalpComponent } from './feature-a/chalp/chalp.component';
import { FeatureAComponent } from './feature-a/feature-a.component';
import { FeatureBComponent } from './feature-b/feature-b.component';
import { SkoneComponent } from './feature-b/skone/skone.component';
const routes: Routes = [
/* { path: 'feature-a', component: FeatureAComponent,
children: [
{ path : 'feature-a/chalp', component: ChalpComponent }
]
},
{ path: 'feature-b', component: FeatureBComponent,
children: [
{ path : 'feature-b/skone', component: SkoneComponent }
]
}
*/
{ path : 'feature-a/chalp', component: ChalpComponent },
{ path : 'feature-b/skone', component: SkoneComponent },
{ path: 'feature-a', component: FeatureAComponent },
{ path: 'feature-b', component: FeatureAComponent },
];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
markup for app.component:
<h1>Inside App-Module now!</h1>
Go to feature A for chalp: <a routerLink="feature-a/chalp">Chalp</a>
Go to feature B for Skone: <a routerLink="feature-b/skone">Skone</a>
<router-outlet></router-outlet>
feature-a routing + module file
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { RouterModule, Routes, RouterOutlet, RouterLink } from '#angular/router';
import { FeatureAComponent } from './feature-a.component';
import { ChalpComponent } from './chalp/chalp.component';
const routes : Routes = [
{ path : '', component : FeatureAComponent },
{ path : 'chalp', component: ChalpComponent}
]
#NgModule({
declarations: [ChalpComponent],
imports: [
CommonModule,
RouterModule.forChild(routes)
]
})
export class FeatureAModule { }
chalp- a component within feature-a
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-chalp',
templateUrl: './chalp.component.html',
styleUrls: ['./chalp.component.css']
})
export class ChalpComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
}
chalp markup
<p>chalp works!</p>
<a routerLink="../">Go back one</a>
The answer is cleaner:
use lazily loaded feature modules.
// root module routing:
router.forRoot([
// this is what ng documentation suggests
{
path: 'admin',
loadChildren: () => import('./items/items.module').then(m => m.ItemsModule)
},
each of these unique route prefixes
existing already in our bloated application.
now is stored and carefully imported depending
on when the contained resources are required
by the user.
...
])
//then in each feature modules' routing module
router.forChild([
// treat the first word as root, so url is not admin/admin!
{ path: '', component: AdminComponent,
children: [
/*All urls in our app which
have 'admin' prefix*/
]
}
]
Two big lessons out of this excursion into typescript:
always know the framework and the way its designed before using it.
not only do the feature modules handle imports and routing, they also each import
a shared module called util which houses the service main module, all types and interfaces, componentry, pipes and directives that the whole app uses.
In the future, knowing this will help me better design applications. The core app is what
all our feature modules plug into and what gets bootstrapped when the application is served. Now there is a unified structure to how imports and exports are structured, and
you never have a question about how to get to a service or interface.

Error at angular CLI production build

I am trying to build the angular version 5 application for production with this command of angular cli version 1.5.2:
ng build --prod
but it gives me this error :
ERROR in Error: Error encountered resolving symbol values statically. Calling fu nction 'FlashMessagesModule', function calls are not supported. Consider replaci ng the function or lambda with a reference to an exported function, resolving sy mbol AppModule in D:/Project/mean-auth-app/angular-src/src/app/app.module.ts, re solving symbol AppModule in D:/Project/mean-auth-app/angular-src/src/app/app.mod ule.ts
It seems angular v5.0 has a conflict with angular2-flash-messages module version 2.0.0.
I did exactly the same thing here to install and setup the flash messages module. I searched but i couldn't find any useful hint. Some people call it a bug and some people could solve their problem with uninstall/install the problematic package.
My app module :
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { FormsModule } from '#angular/forms';
import { RouterModule, Routes } from '#angular/router';
import { HttpModule } from '#angular/http';
import { AppComponent } from './app.component';
import { NavbarComponent } from './components/navbar/navbar.component';
import { LoginComponent } from './components/login/login.component';
import { RegisterComponent } from './components/register/register.component';
import { HomeComponent } from './components/home/home.component';
import { DashboardComponent } from './components/dashboard/dashboard.component';
import { ProfileComponent } from './components/profile/profile.component';
import { AccountService } from './services/account.service';
import { FlashMessagesModule } from 'angular2-flash-messages';
import { JwtModule } from '#auth0/angular-jwt';
import { HttpClientModule } from '#angular/common/http';
import { AuthGuard } from './services/auth-guard.service';
const routes = [
{ path: '', component: HomeComponent },
{ path: 'register', component: RegisterComponent },
{ path: 'login', component: LoginComponent },
{ path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuard]},
{ path: 'profile', component: ProfileComponent, canActivate: [AuthGuard]}
];
#NgModule({
declarations: [
AppComponent,
NavbarComponent,
LoginComponent,
RegisterComponent,
HomeComponent,
DashboardComponent,
ProfileComponent
],
imports: [
BrowserModule,
FormsModule,
HttpModule,
FlashMessagesModule.forRoot(),
RouterModule.forRoot(routes),
HttpClientModule,
JwtModule.forRoot({
config: {
tokenGetter: () => {
return localStorage.getItem('token');
},
whitelistedDomains: ['localhost:4200']
}
})
],
providers: [AccountService, AuthGuard],
bootstrap: [AppComponent]
})
export class AppModule { }
I appreciate any hint to solve this problem.
EDIT: The following will also break the --prod build, but the message marks another problem.
I took a look at the angular2-flash-messages package and the error lies in their code:
They don't add the required metadata of the angular compiler.
There is no solution until following issue is fixed: https://github.com/moff/angular2-flash-messages/issues/31
Old answer:
You aren't allowed to use lambda functions in a decorator.
The error lies here:
config: {
tokenGetter: () => { // <- here
return localStorage.getItem('token');
},
whitelistedDomains: ['localhost:4200']
}
The problem is, that angular will not be able to store all required informations about the decorator if you use a lambda function, but an exported function can be used.
You have to rewrite it to:
export function tokenGetter() {
return localStorage.getItem('token');
}
And you should be able to use it like this in your code:
config: {
tokenGetter: tokenGetter,
whitelistedDomains: ['localhost:4200']
}
Specifying paths to #angular inside AngularCLI's tsconfig.json prevented the error from happening.
"paths": { "#angular/*": ["../node_modules/#angular/*"] }
Reference : link

Application routing overrides modules routing

I've met some interesting situation while developing application using Angular 4.1.1. I've always declared routing in a module and I do it in all modules.
For example, new-cars.routing.module.ts:
import { NgModule } from '#angular/core';
import { RouterModule, Routes } from '#angular/router';
import { NewCarsComponent} from './new-cars.component';
import { NewCarsResolver } from './new-cars.resolver';
#NgModule({
imports: [
RouterModule.forChild([
{
path: 'cars/:id',
component: NewCarsComponent,
resolve: {
card: NewCarsResolver
}
}
])
],
exports: [RouterModule]
})
export class NewCarsRoutingModule { }
Then I've read this article to redirect to "404 Not Found" component, if user inputs not exisiting URL address. And I declared this route in app-routing.module.ts:
export const routes: Routes = [
{ path: '**', component: PageNotFoundComponent }
];
and now all pages show Page not found.
app.module.ts:
import ...;
import { NewCarsModule } from './new-cars/new-cars.module';
import ...;
#NgModule({
imports: [
RouterModule,
BrowserModule,
AppRoutingModule,
HomeModule,
SearchModule,
CoreModule,
NewsCarsModule,
],
declarations: [
AppComponent,
PageNotFoundComponent
],
bootstrap: [AppComponent]
})
export class AppModule { }
My questions is Is it possible to write { path: '**', component: PageNotFoundComponent } just in one place, not in all components?
The main problem here is the order of your routes.
#NgModule({
imports: [
...
NewsCarsModule, // this order is important
AppRoutingModule // where you declared PageNotFoundComponent
],
...
})
export class AppModule {}
See also
https://github.com/angular/angular/issues/12648

Angular2 Unexpected value in Service. Please add annotation

In my Angular2 app am getting the following error Error: (SystemJS) Unexpected value 'ReleasesService' declared by the module 'AppModule'. Please add a #Pipe/#Directive/#Component annotation.
My AppModule:
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { routing } from './app.routes';
import { HttpModule } from '#angular/http';
import { SearchFilter } from '../app/search-filter.pipe';
import { ReleasesService } from '../app/releases/releases.service';
import { AppComponent } from './app.component';
import { HomeComponent } from '../app/home/home.component';
import { ReleasesComponent } from '../app/releases/releases.component';
import { DistroComponent } from '../app/distro/distro.component';
import { ContactComponent } from '../app/contact/contact.component';
#NgModule({
imports: [ BrowserModule, HttpModule, routing ],
declarations: [ AppComponent,
SearchFilter,
HomeComponent,
ReleasesComponent,
ReleasesService,
DistroComponent,
ContactComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
My ReleasesService:
import { Injectable } from '#angular/core';
import { Http, Response } from '#angular/http';
import { Observable } from 'rxjs/Observable';
import { IRelease } from './release';
import 'rxjs/add/operator/map';
#Injectable()
export class ReleasesService {
getReleases() {
return IRelease;
}
}
How to fix it? I reinstalled the Quickstarter (the base for my App), and having the same error when try to create the service.
declarations is only for declarable classes: Components Directives and Pipes
You can add ReleasesService to providers array
#NgModule({
imports: [ BrowserModule ],
declarations: [ AppComponent ],
providers: [ ReleasesService ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
See also
https://angular.io/guide/ngmodule-faq#what-classes-should-i-add-to-declarations
I had a similar problem, occurring while a project had angular2 as dependency and a project dependency (with the failing component) as well. Seems like angular2 metadata gets attached to the direct angular2 dependency, so the component in the project dependency wasn't declared in the angular2 of the project.
Workaround is to remove angular2 from the dependency (declaring it as devDependency there) and only use one angular2 instance.
Be sure the decorator has the caracter #.
If you donĀ“t type # before the decorator function you will have this error message
#Component({ selector: '...', }) -> Correct
Component({ selector: '...', }) -> ERROR MESAGE: 'add a #Pipe/#Directive/#component'

Categories

Resources