I've a few classes I want to be just a plain bean/DTO class, they aren't display #component classes, they're not #Pipe classes nor should they be #Directive (at least I don't think it should be!).
I want to be able to bundle them into a module (they will be used across other modules), but despite several incantations I keep getting errors like this:
When I startup my Angular app (ng serve) it compiles ok, but in the browser (Chrome) console I get an error....
Uncaught Error: Unexpected value 'Accreditation' declared by the module 'ServiceModule'. Please add a #Pipe/#Directive/#Component annotation.
How should I be bundling these classes into a Module for use by other Modules? I don't mind if they are in my service module or in another new 'beans' modules.
Given this module definition (service.module.ts):
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import {MemberService} from "./member/member.service";
import { Accreditation } from "./accreditation";
import {Player} from "./player";
import {Club} from "./club";
import {Coach} from "./coach";
#NgModule({
imports: [CommonModule],
declarations: [Accreditation, Club, Player, Coach],
exports: [Accreditation, Club, Player, Coach],
providers: [MemberService]
})
export class ServiceModule { }
accreditation.ts:
export class Accreditation {
uuid: string;
name :string;
lastComplete: Date;
expires: Date;
inLast6Months: boolean;
type: String;
displayName: String;
hasCompleted: boolean;
}
You don't need to import neither declare your DTOs in app.module.ts. It's available for a direct import in your components, directives, etc..
Simply import it in whichever component/service/directive,pipes you need with other imports:
import { Accreditation } from "./accreditation";
If you wish to share your DTO among several modules, put it in a shared folder and access it with a relative path, i.e.
import { Accreditation } from "./shared/accreditation";
Related
I have been working on creating a service to make http requests and hence I'm using HttpClientModule given by Angular. I have data.serivce.ts file where the service is declared and I'm importing the HttpClient as shown below.
import { Injectable } from '#angular/core';
import { HttpClient} from '#angular/common/http'
#Injectable()
export class DataService {
constructor(private http:HttpClient) {
}
validateLogin(){
return this.http.get('https://someurl')
}
}
Since I'm injecting the dependency of DataService in the providers array of the app.module.ts, I don't understand why I need to import the HttpClientModule again in the app.module.ts
You should look into how angular modules work. Your app.module.ts contains AppModule which is a root module. Every application has at least one module i.e. root module. If you import any module inside your AppModule then its (imported module) components will be accessible to every component of your application.
Thats why to make HttpClient available "everywhere" in the app:
import the HttpClientModule inside AppModule.
Now you can use Services, Components etc defined inside HttpClientModule in your own services or components.
For the variable type information you use on this line
constructor(private http:HttpClient)
Without that import, there would be an error since that type would be unknown.
In the Angular docs it says that the HttpClientModule, "Configures the dependency injector for HttpClient with supporting services for XSRF." So it looks like that's why it would be a prerequisite for using the HttpClient.
https://angular.io/api/common/http/HttpClientModule#description
https://angular.io/tutorial/toh-pt6
https://angular.io/guide/architecture#services
I'm following the docs on angular.io to inject dependencies like services, etc. I did everything they said and when I try to run it, the console keeps telling me:
Uncaught ReferenceError: LedgerService is not defined
I am doing nothing crazy except creating a simple component with a service where both constructors have console.log commands (constructors in both the component and service). I've done everything Angular says to do in their 2 paragraphs that details this feature of Angular.
The component itself is being injected into the main app module (with the service being injected into the component) and both the component and service were created with the Angular CLI. So there isn't much I've even done at all minus trying to inject the service. So I'm not sure where it is going wrong but it is definitely not working and just shows a blank page (when it previously had basic content by default).
I created both units, tried to specify providers in both the app.module and the component.ts file and neither works and yields the same error--when Angular claims either could work. I've also specified it as a private service within the constructor of the component.ts file.
Everything I've seen relating to this is always for Angular 1 or 2. Neither of which are even remotely similar to Angular 4/5.
If you really want to see this code, fine but it's literally just framework and nothing else:
bookkeeper.component.ts:
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-bookkeeper',
templateUrl: './bookkeeper.component.html',
styleUrls: ['./bookkeeper.component.css'],
providers: [LedgerServiceService]
})
export class BookkeeperComponent implements OnInit {
constructor(private service: LedgerServiceService) { }
ngOnInit() {
console.log("Ledger component works!");
}
}
app.module.ts:
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { AppComponent } from './app.component';
import { InterfaceComponent } from './interface/interface.component';
import { BookkeeperComponent } from './bookkeeper/bookkeeper.component';
#NgModule({
declarations: [
AppComponent,
InterfaceComponent,
BookkeeperComponent
],
imports: [
BrowserModule
],
providers: [
LedgerServiceService
],
bootstrap: [AppComponent]
})
export class AppModule { }
ledger-service.service.ts:
import { Injectable } from '#angular/core';
#Injectable()
export class LedgerServiceService {
constructor() {
console.log("wtf");
}
}
LedgerService is actually called LedgerServiceService because I initially created LedgerService manually and then tried to use the AngularCLI to generate a service and named it LedgerService and it created a service called LedgerServiceService. Naming is not what is wrong. I only initially called it simply LedgerService because I figured it would be confusing.
Your examples are missing the import.
Anywhere we use a custom type, we also need to import that type.
For that reason, in both the module and component you will need to add:
import { LedgerServiceService } from './your-path-here'
You can see this in the examples they give on https://angular.io/guide/dependency-injection
In the below code from ../src/app/app.module.ts,
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { AppComponent } from './app.component';
import { HomeComponent } from './home/home.component';
Component consists:
view(../src/app/app.component.html)
logic(../src/app/app.component.ts)
style(../src/app/app.component.css)
Angular application is a tree of components. Good components have high cohesion, i.e. each component contains only elements with related functionality. They are also well encapsulated and loosely coupled.
How modules are different from components?
A component is just a class with the #Component() annotation. Note that .html and .css files might be referenced by the component, certainly not mandatory. The component template might very well be 'inlined' directly in the component configuration, or there simply might not be any html template at all for a given component.
A module is a structural element of an Angular application (and maybe other classes and interfaces). It is also "just a class" with the #NgModule() annotation.
It acts as a logical 'container' for your components, directives, services, pipes, etc... to help you structure your overall source code better.
You can have a look at this existing question : What's the difference between an Angular component and module
A module is something that has components. It wraps them up so you can import and manage them.
Notice when you make a component you can put anything that's decorated as #Injectable in your constructor:
#Component({
selector: 'app-heroes',
templateUrl: './heroes.component.html',
styleUrls: ['./heroes.component.css']
})
export class HeroesComponent implements OnInit {
constructor(private myService: MyService) { }
ngOnInit() {
}
}
And magically you will have a myService to use. This is dependency injection, which is built into Angular - but it's managed on a Module level. In your module you import what other modules you want to be able to use:
imports: [
BrowserModule,
FormsModule
],
define what your module includes:
declarations: [
AppComponent,
HeroesComponent,
MyService
],
export any components (so other modules can import them)
exports: [
HeroesComponent
],
They help organize an application into blocks of functionality. Components are things that tell angular how to render something. Modules compose Components, Pipes, Services etc into 'blocks' that can be compiled by angular or imported and used by others.
Edit to address comment
Taking your specific question about HttpClient. The HttpClient is the service you are using to perform the actions. The HttpClientModule is the module you import into your module, so you can use the service it contains.
You import the module:
#NgModule({
imports: [
BrowserModule,
// Include it under 'imports' in your application module
// after BrowserModule.
HttpClientModule,
],
})
And use the service:
#Component(...)
export class MyComponent implements OnInit {
// Inject HttpClient into your component or service.
constructor(private http: HttpClient) {}
...
}
The HttpClientModule contains within it all you need for the HttpClient to work, and packages it up so you can use it in your own projects.
This particular module only wraps up that one service, but the module could contain a bunch of related services, components, pipes or directives. For example, the RouterModule allows you to use the RouterOutlet and RouterLink directives.
Module in angular is set of Components, Services, Filters, or some another smaller modules too, or we can say where you import all these in order to use later in the app for future use. in a single app there can be one or more than one module may exist.
Whereas, A component controls a patch of screen called a view.
You define a component's application logic—what it does to support the view—inside a class. The class interacts with the view through an API of properties and methods.
Refer this guide for more details:
https://angular.io/guide/architecture
I am pretty new in Angular 2. I am studying how to create modules into an Angular app and I have the following doubt related a tutorial that I am following.
My doubt is related to the routing.
So in my example there is defined this AuthModule module:
import { NgModule } from '#angular/core';
import { FormsModule } from '#angular/forms';
import { SigninComponent } from './signin/signin.component';
import { SignupComponent } from './signup/signup.component';
import { AuthRoutingModule } from './auth-routing.module';
#NgModule({
// Components and directives used by the module:
declarations: [
SigninComponent,
SignupComponent
],
// Import modules used by this features module:
imports: [
FormsModule,
AuthRoutingModule
]
})
export class AuthModule {}
and I have the related rotues configuration class defined:
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { ShoppingListComponent } from './shopping-list/shopping-list.component';
const appRoutes: Routes = [
{ path: '', redirectTo: '/recipes', pathMatch: 'full' },
{ path: 'shopping-list', component: ShoppingListComponent }
];
#NgModule({
imports: [RouterModule.forRoot(appRoutes)],
exports: [RouterModule]
})
export class AppRoutingModule {
}
So I think that the export keyword means that the content related to this class can be exported and used somewhere else (in this case I think into the imports array of the AuthModule class).
Is it? Or am I missing something? What it the exact meaning of the export statment?
I am not understanding if it is something related to Angular or more generally to TypeScript (because here I found https://www.typescriptlang.org/docs/handbook/modules.html). So it seems to me that this module concept is not directly bounded to Angular 2 framework but is a TypeScript concept to subdivide our code in a smart way (then Angular 2 can use this kind of feature of the language).
Is it or am I missing something?
Angular imports/exports and TypeScript imports/exports are two different concepts.
TypeScript imports/exports work at language level to make it clear what
a used identifier references exactly. This is entirely unrelated to Angular.
So, if you use FormsModule there can't be any ambiguity, what FormsModule is meant. If there is more than one FormsModule in your code or any of your dependencies, then you need to make it clear with imports which one is meant. You can't import 2 FormsModule from different locations without disambiguation (for example using as foo in the import and then reference it using foo.FormsModule).
This way you can use code from arbitrary 3rd-party libraries and avoid name collisions.
Angular imports/exports are used to make the content of one module available to be used in another module.
Your:
imports: [
FormsModule,
AuthRoutingModule
]
Allows you to use the directives from FormsModule and AuthRoutingModule in AuthModule and registers the services provided by these modules in the AppModule scope or the closed lazy-loaded root scope.
If you reference any of Angulars directives or services in TypeScript code, you also need to add TypeScript imports. Above FormsModule and AuthRoutingModule need to be imported with TypeScript imports, to make the Angular imports: [...] work.
For example like
<form #f="ngForm">
<input type="text">
</form>
works only if FormsModule is listed in imports: [ ... ] of your current module.
There is no TypeScript import required, because there is no TypeScript code.
Yes you are right by using export keyword before your typescript class you can use that class somewhere else .. in your project
Does anyone know if it’s possible to export enums in Angular modules?
If not, are there any best practises to ship enums within Angular modules?
// not working example
// i dont know how to export GreatEnum
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { GreatComponent } from './great.component';
import { GreatEnum } from './great.enum';
#NgModule({
imports: [
CommonModule
],
declarations: [GreatComponent ],
exports: [GreatComponent ]
})
export class GreatModule {
}
Why you need to export enum from the modules?. It is not necessary . It is like an interfaces and classes. You can use it everywhere, except directly in the templates.
You can just import them in any file which you want and use there. For them there is no error like
Directive or Component is not found
If you are writing libraries, you have to export enums with the keyword const
export const enum <ENUM_NAME>