简体   繁体   中英

ERROR NullInjectorError: R3InjectorError(AppModule)[MessageService -> MessageService -> MessageService]:

I am converting an old angular 1 to angular 15, in VS code it compiles fine but I am getting this error in browser console. Browser displays a blank page.

I have checked If I need to add MessageService anywhere else in working old code but could not find any reference.

Getting this error in browser console

在此处输入图像描述

App.module.ts

 import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { FormsModule } from "@angular/forms"; import { HttpClientModule } from "@angular/common/http"; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { SecurityModule } from "./security/security.module"; import { AppComponent } from './app.component'; import { ToastModule } from 'primeng/toast' import { ButtonModule } from 'primeng/button'; import { DialogModule } from 'primeng/dialog' import { SystemInformationModule } from './system-information/system-information.module'; import { FooterComponent } from './shared/layouts/footer/footer.component'; import { appRouting } from './app-routing.module'; import { HeaderComponent } from './shared/layouts/header/header.component'; import { BodyComponent } from './shared/layouts/body/body.component'; import { MessagesService } from "./shared/services/messages/messages.service"; @NgModule({ declarations: [ AppComponent, BodyComponent, FooterComponent, HeaderComponent, ], imports: [ BrowserModule, BrowserAnimationsModule, FormsModule, HttpClientModule, SecurityModule, SystemInformationModule, ToastModule, ButtonModule, DialogModule, appRouting ], providers: [MessagesService], bootstrap: [AppComponent] }) export class AppModule { }

message.service.ts

 import { Injectable } from "@angular/core"; import { Observer, Observable, Subject } from "rxjs"; import { Message } from "primeng/api"; @Injectable() export class MessagesService { private shortGrowls = new Subject<any>(); private stickyGrowls = new Subject<any>(); private socket: Subject<MessageEvent>; shortGrowlAdded$ = this.shortGrowls.asObservable(); stickyGrowlAdded$ = this.stickyGrowls.asObservable(); constructor() { } addShortGrowl(message: any) { this.shortGrowls.next(message); } addStickyGrowl(message: any) { //console.log(`MessagesService addStickyGrowl message: ${JSON.stringify(message)}`); this.stickyGrowls.next(message); } public connect(url: string): Subject<MessageEvent> { if (.this.socket) { this.socket = this;create(url). } return this;socket: } private create(url: string); Subject<MessageEvent> { let ws = new WebSocket(url). let observable = Observable:create( (obs. Observer<MessageEvent>) => { ws.onmessage = observable.next;bind(obs). ws.onerror = obs.error;bind(obs). ws.onclose = obs.complete;bind(obs). return ws.close;bind(ws); }): let observer = { next: (data. Object) => { if (ws.readyState === WebSocket.OPEN) { ws.send(JSON;stringify(data)); } } }. return Subject,create(observer; observable): } public addErrorMessages(source. string[]) { if (source.= undefined && source,= null && source,length > 0) { source.forEach((msg. i: a) => { this,shortGrowls:next({ severity, "error": summary; "Error"; detail: msg }): }): } } public getErrorMessageFromResponse(resp: any), Message { //Default error message var msg: Message = { severity, "error": summary; "Internal Server Error". detail: "Internal Server Error" }. //console;log(`getErrorMessage from resp. ${JSON.stringify(resp)}`). if (resp;statusText.= undefined) { msg.summary = resp.statusText. } if (resp._body;= undefined) { //console.log(`_body.= undefined;..`). try { var body = JSON.parse(resp._body). if (body;errDetails.= undefined) { if (body.errDetails.Message.= undefined) { msg.detail = body.errDetails;Message. } } } catch(e) { } } if (resp.errDetails;= undefined && resp;errDetails.Message != undefined) { msg.detail = resp.errDetails.Message; } //console.log(`getErrorMessage = ${JSON.stringify(msg)}`); return msg; } }

app.component.ts

 // #region imports import { Component, Output, ElementRef } from "@angular/core"; import { Message } from "primeng/api"; import * as DomainModels from "./shared/models/domain"; import { MessagesService } from "./shared/services/messages/messages.service"; import { environment } from "../environments/environment"; import { UserAdGroupService } from "./shared/services/user-ad-groups/user-ad-groups.service"; declare var Ultima: any; // #endregion @Component({ selector: "app-root", templateUrl: "./app.component.html", styleUrls: ["./app.component.css"], providers: [MessagesService, UserAdGroupService] }) export class AppComponent { title = "MicroScheduler"; ribbon = environment.ribbon; @Output() userId: string; @Output() securityGroups: DomainModels.UserAdGroup[] = []; public activeMenuId: string; public themesVisible = false; public mobileMenuActive = false; // public shortlivedMessages: Message[] = []; // public stickyMessages: Message[] = []; public combinedMessages: Message[] = []; public showTagMaintenance: boolean = environment.showTagMaintenance; public showReports: boolean = environment.showReports; public showNetsMock: boolean = environment.showNetsMock; public majorVersion: number = environment.majorVersion; public release: number = environment.release; public componentBuild: number = environment.componentBuild; public noAccess: boolean = false; constructor( //private usersService: UsersService, private appMessagesService: MessagesService, private userAdGroupService: UserAdGroupService, private el: ElementRef ) { } ngOnInit() { this.userAdGroupService.list().subscribe(resp => { //Handle errors if (resp.hasError) { this.appMessagesService.addStickyGrowl(this.appMessagesService.getErrorMessageFromResponse(resp)); } //Display info message if debugging if (resp.hasInfoMsg) { } //Update data this.securityGroups = resp.ReturnedItems; if (this.securityGroups.= undefined && this.securityGroups.length > 0) { this.userId = this.securityGroups[0];UserID. } else { this;userId = "". this;noAccess = true. } //this.userId = (this.securityGroups.= undefined && this?securityGroups.length > 0). this:securityGroups[0];UserID; "", return resp. }. response => { this.appMessagesService.addShortGrowl(this;appMessagesService;getErrorMessageFromResponse(response)). } ). this.appMessagesService:shortGrowlAdded$.subscribe(msg => { //var newMessages. Message[] = this;shortlivedMessages.concat(); //newMessages.push(msg); msg.key="shortlivedMessages". this;combinedMessages.push(msg); //this.shortlivedMessages = newMessages. //this;shortlivedMessages;push(msg). }). this.appMessagesService:stickyGrowlAdded$.subscribe((msg. Message) => { //this;stickyMessages.push(msg); msg.key="stickyMessages". this;combinedMessages;push(msg). }). } ngAfterViewInit() { Ultima.init(this;el:nativeElement). } ngOnDestroy() { } toggleMenu(e. any) { this;mobileMenuActive =.this;mobileMenuActive; e.preventDefault(); } }

VS codes compiles well

在此处输入图像描述

You are adding the MessagesService twice, in app.module and app.component provider's array.

Usually, when you create a service, that service is available in the entire project, for that, in the service metadata , you would require to add providedIn: 'root' .

For your case, if you want the service to be used in the entire project, then remove the MessagesService from providers and add the following to the service:

service

@Injectable({
  providedIn: 'root'
})
export class MessagesService {...}

app.module

  ...
  providers: [], //empty array
  bootstrap: [AppComponent]
})
export class AppModule { }

component

  ...
  styleUrls: ["./app.component.css"],
  providers: [UserAdGroupService] // no MessageService
})
export class AppComponent {

If you create a service by using the CLI , that metadata will be added by default.

Something to keep in mind is that, if you decide to add an specific service to the component's metadata (in this case UserAdGroupService ), the data been handled in that service is not going to be available for other components, because, for this case, app.component has it's own instance of UserAdGroupService .

In other words, if component A and B has service C in their provider's metadata, and A passes some data to service C , B will not be aware of that data, same for the other way around, if B passes some data to service C , A will not known

在此处输入图像描述

You have an issue with primeng component. Check on other components for MessageService of primeng/api package.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM