What could be causing the "serviceName error: No provider found" message to appear?

Currently, I am working on sharing a value between two components in Angular. The setup involves a ProjectView component that renders a ProjectViewBudget component as a "child" (created within a dynamic tab component using ComponentFactoryResolver) with the help of a service. The child component is responsible for modifying this shared value, while the parent component simply subscribes to it. Although I have only implemented the functionality in the child component to test its behavior, I encountered an error. Why did this error occur?

[ Service ]

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';

@Injectable()
export class BudgetYearSelectionService {
    private yearSource = new BehaviorSubject(undefined);
    selectedYear = this.yearSource.asObservable();

    selectYear(year: number): void {
        this.yearSource.next(year);
    }
}

[ Child ]

...
import { BudgetYearSelectionService, ProjectPrintService } from 'app/modules/project/service';
import { Subscription } from 'rxjs';

@Component({
    selector: 'ain-project-view-budget',
    templateUrl: './budget.component.html',
    styleUrls: ['./budget.component.scss'],
    encapsulation: ViewEncapsulation.None,
    changeDetection: ChangeDetectionStrategy.OnPush
})
export class ProjectViewBudgetComponent implements OnInit, OnDestroy {

    years: Array<number>;
    year: number;

    private subscriptions: Array<Subscription> = [];

    constructor(
        private store: Store<any>,
        private ref: ChangeDetectorRef,
        private printService: ProjectPrintService,
        private budgetYearSelection: BudgetYearSelectionService
    ) { }

    ngOnInit(): void {
        ...
        this.subscriptions.push(this.budgetYearSelection.selectedYear.subscribe(year => this.year = year));
    }

    ngOnDestroy(): void {
        this.subscriptions.forEach(subscription => {
            subscription.unsubscribe();
        });
    }

    onYearChange(year?: number): void {
        this.budgetYearSelection.selectYear(year);
        this.component = year === undefined ? ProjectViewBudgetOverviewComponent : ProjectViewBudgetYearComponent;
    }
    ...
}

[ app.module.ts ]

import { registerLocaleData } from '@angular/common';
import { HttpClient, HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import localeNl from '@angular/common/locales/en-NL';
import localeNlExtra from '@angular/common/locales/extra/en-NL';
import { LOCALE_ID, NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { RouteReuseStrategy } from '@angular/router';
import { ServiceWorkerModule } from '@angular/service-worker';
import { EffectsModule } from '@ngrx/effects';
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
import { PerfectScrollbarModule } from 'ngx-perfect-scrollbar';
import { environment } from '../environments/environment';
import { RoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { AppInterceptor } from './app.interceptor';
import { LayoutModule } from './layout';
import { MaterialModule } from './material';
import { AinModule } from './modules/ain.module';
import { NotificationModule } from './modules/notification/notification.module';
import { PermissionModule } from './modules/permission';
import { CustomRouteReuseStategy } from './modules/shared/custom-route-reuse.strategy';
import { OfflineComponent, PageNotFoundComponent } from './pages';
import { AppEffects } from './redux/app.effects';

export function createTranslateLoader(http: HttpClient): TranslateHttpLoader {
    return new TranslateHttpLoader(http, 'assets/i18n/', '.json');
}

registerLocaleData(localeNl, localeNlExtra);

@NgModule({
    imports: [
        BrowserModule,
        BrowserAnimationsModule,
        FormsModule,
        ReactiveFormsModule,
        MaterialModule,
        HttpClientModule,
        TranslateModule.forRoot({
            loader: {
                provide: TranslateLoader,
                useFactory: (createTranslateLoader),
                deps: [HttpClient]
            }
        }),
        EffectsModule.forFeature([AppEffects]),
        PerfectScrollbarModule,
        MaterialModule,
        AinModule,
        NotificationModule,
        PermissionModule.forFeature(),
        RoutingModule,
        LayoutModule,
        ServiceWorkerModule.register('ngsw-worker.js', { enabled: environment.production })
    ],
    declarations: [
        AppComponent,
        OfflineComponent,
        PageNotFoundComponent
    ],
    bootstrap: [AppComponent],
    providers: [
        { provide: HTTP_INTERCEPTORS, useClass: AppInterceptor, multi: true },
        { provide: LOCALE_ID, useValue: 'en-NL' },
        { provide: RouteReuseStrategy, useClass: CustomRouteReuseStategy }
    ]
})
export class AppModule {
}

[ Error ]

core.js:5873 ERROR NullInjectorError: R3InjectorError(AppModule)[BudgetYearSelectionService -> BudgetYearSelectionService -> BudgetYearSelectionService]: 
  NullInjectorError: No provider for BudgetYearSelectionService!

To implement this functionality, I referred to the fourth example outlined in this guide:

Answer №1

Have you integrated a service into a specific module?

If not, consider including 'providedIn: root' when declaring the service:

@Injectable({
  providedIn: 'root',
})
export class BudgetYearSelectionService {

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Error in ReactJS: TypeError - Trying to convert undefined or null as an object

Here is the affected code with Typescript errors in local. The component name is correct: {template.elements.map((element: TemplateElementModel, i) => { const stand = roomStands?.find( (stand: ExhibitorModel) => stand.standN ...

Combining two elements in Angular 2

I am looking to find the intersection of two objects. My goal is to compare these objects and if they have matching values on corresponding keys, then I want to add them to a new object. obj1 = { "Projects": [ "test" ], "Companies": [ "facebook", "google ...

Experience the latest happenings in SAP Spartacus 4.0 by signing up for updates directly from

I am facing an issue while trying to register an event in Spartacus import { Injectable } from '@angular/core'; import { CartDetailsComponent, PromotionService} from '@spartacus/storefront'; import { ActiveCartService, SelectiveCartServ ...

Converting HTML to PDF with rtl support using the JavaScript library jsPDF

I'm attempting to convert HTML to PDF using jsPDF in an Angular 5 project. Below is the code I have so far: import * as jsPDF from "jspdf"; . . . htmlToPdf(){ var doc=new jsPDF(); var specialElementHandlers = { '#content' : function ...

Grunt is your go-to resource for instructions on executing these tasks before the main program

Before launching my app, I need to make sure a specific grunt task is executed first: node app.js I'm having trouble finding information on how to automatically run and complete a Grunt task before initiating a node command. In particular, I have T ...

ngx-charts-pie-chart angular5 library data structure

I am utilizing the ngx-charts library in my current project. When using the onSelect method, I noticed that it only returns an object with attributes value and name, even though my list contains three attributes: value, name, and id. Upon examining the s ...

Filtering an array of objects based on a specific condition in TypeScript

I am trying to filter the array object data where the count of Failed is greater than 0. Unfortunately, the code below is not working as expected. ngOnInit() { this.employeeService.getProducts().subscribe((data:any) => { console.log(data); this. ...

How can one go about constructing abstract models using Prisma ORM?

Among my various prisma models, there are common fields such as audit fields like created_at and updated_at. model User { id Int @id @default(autoincrement()) created_at DateTime @default(now()) updated_at DateTime @updatedAt email ...

I'm currently working on creating an online store using Next.js and TypeScript, but I'm struggling to effectively incorporate my fake product data array into the site

"using client" import Container from "@/components/Container"; import ProductDetails from "./ProductDetails"; import ListRating from "./ListRating"; import { products } from "@/utils/products"; interface I ...

The module 'AppModule' has imported an unexpected pipe. To resolve this issue, please include a @NgModule annotation

I have successfully created a custom pipe to remove duplicate items from an array and have imported it into my app.module.ts file Below is the code snippet: app.module.ts import { UniquePipe } from './_pipe/uniquePipe'; @NgModule({ imports: ...

Recursively map elements of a TypeScript array to keys of an object

I am looking to create a structured way to specify paths for accessing objects, ensuring that the path is correctly typed based on the object type. Let me illustrate with an example. Consider the following data: const obj = { name: 'Test', ...

Create a series of buttons in Angular 2 that are linked to components with a click event

I am facing an issue with a component that generates a list of buttons, where I want to connect the click event to show a child component. The problem is that my current implementation using a local variable causes all buttons to display the last child com ...

Resizing cell height in an HTML table is not supported by Angular 5

In my angular application, I've implemented a component that represents a basic HTML table. However, I'm facing an issue with reducing the height of cells within the table. It seems like my CSS styling is not affecting the display as desired. He ...

Prioritizing the validation of form controls takes precedence over redirecting to a different URL in Angular 2

Within an HTML page, there is a form with validation and an anchor tag as shown below: <form #loginForm="ngForm" (ngSubmit)="login()" novalidate> <div class="form-group"> <label for="email">Email</label> <i ...

Filter array to only include the most recent items with unique names (javascript)

I'm trying to retrieve the most recent result for each unique name using javascript. Is there a straightforward way to accomplish this in javascript? This question was inspired by a similar SQL post found here: Get Latest Rates For Each Distinct Rate ...

My goal is to create a comprehensive collection of stories showcasing all Material UI components in React

Looking for a way to efficiently import all MUI components stories into my storybook. Is there a tool or repository available that can automate the generation of these stories, or perhaps has pre-written stories for all MUI components? I attempted to cre ...

Creating interactive carousel slides effortlessly with the power of Angular and the ngu-carousel module

I'm currently tackling the task of developing a carousel with the ngu-carousel Angular module, available at this link. However, I'm facing some challenges in configuring it to dynamically generate slides from an array of objects. From what I&apos ...

Transforming time into luxon time frames and hours

Is there a way to convert this block of code from moment.js to luxon? Here is the code snippet for reference: The following code is written using moment.js, but I would like to achieve the same functionality using luxon. timezone: null, getIn: moment() ...

Unit testing in Angular involves using the spyOn function to mock classes or functions imported

Trying to ensure a function call from node_modules is made using a spy. For instance, in obs.d.ts: export declare module Obs { class MyService { func(params: Object): Promise<void>; Thus, I aim to spy on func() In my ...

Enhancing Vue functionality with vue-class-component and Mixins

In my Vue project, I am using vue-class-component along with TypeScript. Within the project, I have a component and a Mixin set up as follows: // MyComp.vue import Component, { mixins } from 'vue-class-component' import MyMixin from './mixi ...