在为我的功能模块创建新的模块并将它们的路径从app.module.ts中分离出来后,我得到了以下错误信息。
core.js:6185 ERROR Error: Uncaught (in promise): NullInjectorError: R3InjectorError(AppModule)[LoginService -> HttpClient -> HttpClient -> HttpClient]:
NullInjectorError: No provider for HttpClient!
NullInjectorError: R3InjectorError(AppModule)[LoginService -> HttpClient -> HttpClient -> HttpClient]:
NullInjectorError: No provider for HttpClient!
at NullInjector.get (core.js:1076)
at R3Injector.get (core.js:16629)
at R3Injector.get (core.js:16629)
at R3Injector.get (core.js:16629)
at injectInjectorOnly (core.js:931)
at Module.ɵɵinject (core.js:941)
at Object.LoginService_Factory [as factory] (login.service.ts:10)
at R3Injector.hydrate (core.js:16865)
at R3Injector.get (core.js:16617)
at NgModuleRef$1.get (core.js:36027)
at resolvePromise (zone-evergreen.js:798)
at resolvePromise (zone-evergreen.js:750)
at zone-evergreen.js:860
at ZoneDelegate.invokeTask (zone-evergreen.js:399)
at Object.onInvokeTask (core.js:41264)
at ZoneDelegate.invokeTask (zone-evergreen.js:398)
at Zone.runTask (zone-evergreen.js:167)
at drainMicroTaskQueue (zone-evergreen.js:569)
at ZoneTask.invokeTask [as invoke] (zone-evergreen.js:484)
at invokeTask (zone-evergreen.js:1621)
我正在创建一个简单的登录服务。从一个欢迎页面上,一旦用户点击 "播放 "按钮,登录页面就会出现。然而,每当我在点击相应的按钮时,我就会得到上述错误。而这似乎是在我把登录功能分离到一个功能模块中后开始出现的。然而,我的服务有注入器定义为。
@Injectable({
providedIn:'root'
})
因此,这意味着将只创建一个服务实例,并将在整个APP中共享。但是,我现在很疑惑,我需要在我的功能模块中的某个地方声明我的服务吗?我需要在我的功能模块中的某个地方声明我的服务吗?我已经正确导入。
import { HttpClientModule } from '@angular/common/http';
在我的app.module.ts中。这里是我的app.module.ts。
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
//import { RouterModule } from '@angular/router';
import { FormsModule } from '@angular/forms';
import { ReactiveFormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { WelcomeComponent } from './home/welcome.component';
import { ActivityComponent } from './shared_component/activitiy-progress.component';
import { SmartWatchComponent } from './smart-watch/smart-watch.component';
import { SmartPhoneComponent } from './smart-phone/smart-phone.component';
import { SmartPhoneMenuComponent } from './smart-phone-menu/smart-phone-menu.component';
import { GameStartComponent } from './game-start/game-start.component';
//import { UserLoginComponent } from './user-login/user-login.component';
import { PageNotfoundComponent } from './page-notfound/page-notfound.component';
import { ResetPasswordComponent } from './reset-password/reset-password.component';
import { UserSignupComponent } from './user-signup/user-signup.component';
import { UserCalendarComponent } from './user-calendar/user-calendar.component';
import { UserNewsComponent } from './user-news/user-news.component';
import { UserStorageComponent } from './user-storage/user-storage.component';
import { TodoListComponent } from './todo-list/todo-list.component';
import { AuthenticationModule } from './authentication/authentication.module';
import { LoginService } from './login.service';
import { AppRoutingModule } from './app-routing.module';
@NgModule({
declarations: [
AppComponent,
WelcomeComponent,
ActivityComponent,
SmartWatchComponent,
SmartPhoneComponent,
SmartPhoneMenuComponent,
GameStartComponent,
PageNotfoundComponent,
//ResetPasswordComponent,
//UserLoginComponent,
//UserSignupComponent,
UserCalendarComponent,
UserNewsComponent,
UserStorageComponent,
TodoListComponent
],
imports: [
BrowserModule,
HttpClientModule,
FormsModule,
ReactiveFormsModule,
AuthenticationModule,
AppRoutingModule
],
// providers: [LoginService],
providers : [],
bootstrap: [AppComponent]
})
export class AppModule { }
这是我的功能模块。
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import {RouterModule} from '@angular/router';
import { FormsModule,ReactiveFormsModule } from '@angular/forms';
import { UserLoginComponent } from '../user-login/user-login.component';
import { UserSignupComponent } from '../user-signup/user-signup.component';
import { ResetPasswordComponent } from '../reset-password/reset-password.component';
@NgModule({
imports: [
CommonModule,
RouterModule.forChild([
{path:'login',component: UserLoginComponent},
{path:'signup',component: UserSignupComponent},
{path:'reset-password',component: ResetPasswordComponent},
// {path:'',redirectTo:'login',pathMatch:'full'}
]),
FormsModule,
ReactiveFormsModule
],
declarations: [
UserLoginComponent,
UserSignupComponent,
ResetPasswordComponent
],
})
export class AuthenticationModule { }
这里是服务。
import { Injectable } from '@angular/core';
import {HttpClient,HttpErrorResponse} from '@Angular/common/http';
import { Observable, throwError } from 'rxjs';
import{map,catchError} from 'rxjs/operators';
@Injectable({
providedIn: 'root',
})
export class LoginService {
private loginUrl : string;
constructor(private http:HttpClient){}
getCurrentUserInfo(loginInfo) : Observable<any>{
this.loginUrl = <my-url>; //for privacy I had to omit the URL
console.log("this.loginUrl =", this.loginUrl);
return this.http.get<any>(this.loginUrl)
.pipe(map(response => response as any),
catchError(this.handleError));
}
private handleError(err:HttpErrorResponse){
let errorMessage = '';
if(err.error instanceof ErrorEvent){
errorMessage = `An error has occurred ${err.error.message}`;
}else{
errorMessage = `server returned code: ${err.status}, error message is: ${err.message} `;
}
console.error(errorMessage);
return throwError(errorMessage);
}
}
这是我的登录组件。
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { FormGroup, FormControl } from '@angular/forms';
import { LoginService } from '../login.service';
@Component({
selector: 'app-user-login',
templateUrl: './user-login.component.html',
styleUrls: ['./user-login.component.css']
})
export class UserLoginComponent{
testId = "testuser";
testPwd = "pwd";
userLoginForm = new FormGroup({
userId : new FormControl(''),
password : new FormControl('')
});
constructor(private loginService : LoginService, private router : Router){}
onLoginSubmit(){
let loginInfo = {
id : this.userLoginForm.value.userId,
password : this.userLoginForm.value.password
}
if(loginInfo.id === "" || loginInfo.password === ""){
alert("Please enter Id & passowrd");
}else if(loginInfo.id === this.testId){
if(loginInfo.password === this.testPwd){
this.router.navigate(['/game-start']);
}else{
alert("password doesn't exist");
this.router.navigate(['/reset-password']);
}
}else{
alert("userId doesn't exist");
}
this.loginService.getCurrentUserInfo(loginInfo).subscribe({
next : data => console.log("returned data : " , data)
});
}
}
这是我的欢迎组件。每当它在导航到登录页面的时候,就会出现错误。
import { Component } from '@angular/core';
import { Router } from '@angular/router';
@Component({
selector : 'welcome',
templateUrl: './welcome.component.html',
styleUrls : ['./welcome.component.css']
})
export class WelcomeComponent {
public pageTitle = 'SurvCovid App';
submitted = false;
constructor(private router: Router){}
onSubmit(){
this.submitted = true;
this.processInitialServerCommunitaion();
}
processInitialServerCommunitaion(){
//this.ngZone.run(() => this.router.navigate(['/app-start']))
//this.router.navigate(['/game-start'], {state: {"Test":"test"}});
this.router.navigate(['/login']);
//alert('from game start');
}
}
这是我的应用路由模块。
import {NgModule} from '@angular/core';
import {RouterModule} from '@angular/router';
import { UserCalendarComponent } from './user-calendar/user-calendar.component';
import { UserNewsComponent } from './user-news/user-news.component';
import { UserStorageComponent } from './user-storage/user-storage.component';
import { TodoListComponent } from './todo-list/todo-list.component';
import { SmartPhoneMenuComponent } from './smart-phone-menu/smart-phone-menu.component';
import { GameStartComponent } from './game-start/game-start.component';
//import { ResetPasswordComponent } from './reset-password/reset-password.component';
import { PageNotfoundComponent } from './page-notfound/page-notfound.component';
import { WelcomeComponent } from './home/welcome.component';
const ROUTES = [
//{path:'login',component: UserLoginComponent},
// {path:'signup',component: UserSignupComponent},
{path:'welcome',component: WelcomeComponent},
{path:'calendar',component: UserCalendarComponent},
{path: 'news',component:UserNewsComponent},
{path: 'storage',component:UserStorageComponent},
{path: 'todo-list',component:TodoListComponent},
{path : 'smartPhone-menu',component:SmartPhoneMenuComponent},
{path : 'game-start',component :GameStartComponent},
{path:'',redirectTo:'welcome',pathMatch:'full'},
// {path:'reset-password',component: ResetPasswordComponent},
{path : '**',component : PageNotfoundComponent}
/*{path:'**',redirectTo:'welcome', pathMatch: 'full'}*/
];
@NgModule({
imports: [
RouterModule.forRoot(ROUTES)
],
exports : [RouterModule]
})
export class AppRoutingModule{}
这是我使用的版本。
Package Version
-----------------------------------------------------------
@angular-devkit/architect 0.900.7
@angular-devkit/build-angular 0.900.7
@angular-devkit/build-optimizer 0.900.7
@angular-devkit/build-webpack 0.900.7
@angular-devkit/core 9.0.7
@angular-devkit/schematics 9.0.7
@ngtools/webpack 9.0.7
@schematics/angular 9.0.7
@schematics/update 0.900.7
rxjs 6.5.4
typescript 3.7.5
webpack 4.41.2
我正在学习Angular,对这个问题相当迷茫。我在类似的stakoverflow帖子中搜索了解决方案,但大多数人都建议导入HttpClientModule,我已经这么做了。而且,好像也没有人在加载服务的时候,在路由加载组件的时候遇到这个问题。这就是为什么我觉得这是一个新问题。因此,任何帮助都将是非常感激的。
你可以通过修改以下内容来指定服务应该在模块中提供。providedIn
值。
替换
@Injectable({
providedIn: 'root',
})
与。
@Injectable({
providedIn: AuthenticationModule,
})
读这个 文章 更多信息
在您的功能模块上,声明提供者为
@NgModule({
imports: [
CommonModule,
RouterModule.forChild([
{path:'login',component: UserLoginComponent},
{path:'signup',component: UserSignupComponent},
{path:'reset-password',component: ResetPasswordComponent},
// {path:'',redirectTo:'login',pathMatch:'full'}
]),
FormsModule,
ReactiveFormsModule
],
declarations: [
UserLoginComponent,
UserSignupComponent,
ResetPasswordComponent
],
providers:[LoginService]
})