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

Warning: The parameter type in the Node JS project is not compatible with the argument type

Upon running this code in WebStorm, I encountered a warning: Argument type {where: {email: userData.emil}} is not assignable to parameter type NonNullFindOptions<Model["_attributes"]> Can someone explain this warning to me? This project ...

What is the process for discovering the kinds of models that can be generated with a Prisma client?

Ensuring data type correctness when creating a Prisma model named 'bid' is crucial. With auto-generated prisma types available, understanding the naming convention and selecting the appropriate type can be confusing. The bid schema looks like th ...

The RxDB Angular2-cli error message. "Cannot assign a 'Promise<void>' to a 'Promise<any>' parameter."

I've been grappling with getting RxDB to function properly in a fresh project I initiated using the Angular CLI. Here's my process: ng new <Projectname> After that, I installed RxDB by running: npm install rxdb Following the example p ...

Solving the issue of refreshing HTML Canvas drawings in Vue3 using the Composition API

In my typescript code base, I have successfully created a Sudoku board by directly manipulating the DOM and utilizing an HTML Canvas element with its API. Now, I am looking to elevate my project to a full website and integrate what I have into a Vue3 proj ...

The panel header is clickable and overlaps with the header buttons

My panel component includes a header with a title and buttons positioned in the right corner. Currently, the downward arrow (chevron) is used to toggle the expansion/minimization of the panel's contents. When I attempt to make the header clickable to ...

Receiving a notification when attempting to log in with incorrect credentials

I am currently working on an Angular login page implementation using a username and password setup. When the user enters incorrect credentials, I want to display an alert message indicating the same. Here is the HTML code snippet for the form: <form [f ...

Tips for implementing a hover effect across the entire line in a line chart using Chart.js

initializeChart(): void { var myGraph = new Chart('myGraph', { type: 'bar', data: { labels: ['Modes'], datasets: [ { label: 'A', data: [this.data.a], borderColor: ' ...

Variations in comparing tuple types in TypeScript

Exploring the TypeScript Challenge, there is a particular problem known as IsNever. The task at hand is to create a type called IsNever that takes input of type T. If the resolved type equates to never, the output should be true; otherwise, it should be fa ...

Revamping elements according to ordered array. Angular version 4.3

Dealing with an array of data that needs to be sorted for displaying in a component seems to be a challenge. Despite having a functional code sample demonstrating the concept, the sorting is not reflected in the Angular app's DOM. The original data i ...

TypeScript utility function that retrieves properties from an interface based on a specified type

Is there a way to create a new object type that includes only properties from another Object that match specific types, as opposed to property names? For example: interface A { a: string; b: number; c: string[]; d: { [key: string]: never }; } int ...

Error: "Reflect.getMetadata function not found" encountered during execution of Jenkins job

My Jenkins job is responsible for running tests and building an image. However, I am encountering issues with the unit tests within the job. task runTests(type: NpmTask) { dependsOn(tasks['lintTS']) args = ['run', 'test&ap ...

Steps for setting up an Angular project as a dependency in the package.json file of another Angular project

I currently have three separate Angular cli projects labeled as X, Y, and Z. My goal is to designate [X] as the parent project and include Y and Z as npm package dependencies within X. This means that the package.json file for [X] will list the dependencie ...

Exploring Angular2: A demonstration showcasing concurrent http requests (typeahead) using observables

Currently, I am working on several cases within my app that require the following sequence of events: Upon triggering an event, the desired actions are as follows: List item Check if the data related to that context is already cached; if so, serve cache ...

Date selection feature in Material UI causing application malfunction when using defaultValue attribute with Typescript

Recently, I discovered the amazing functionality of the Material UI library and decided to try out their date pickers. Everything seemed fine at first, but now I'm facing an issue that has left me puzzled. Below is a snippet of my code (which closely ...

Tips for remembering to reactivate the Protractor Angular synchronization feature

Our test codebase is quite large, with around 10,000 lines of JavaScript code. In certain situations, we find it necessary to disable Protractor-to-Angular synchronization using the following line of code: browser.ignoreSynchronization = true; However, o ...

Transitioning from AngularJS to Angular 2: Exploring Alternatives to $rootScope.$on

Our journey with the AngularJS project has begun on the path towards the modern Angular. The ngMigration utility advised me to eliminate all dependencies on $rootScope since Angular does not have a concept similar to $rootScope. While this is straightforw ...

Leveraging global attributes beyond Vue components - Vue 3

I have created custom service instances in main.ts app.config.globalProperties.$service1 = new Service1(); app.config.globalProperties.$service2 = new Service2(); While I can use these instances inside Vue components, I also want to be able to utilize the ...

What is the best way to pass a conditional true or false value to React boolean props using TypeScript?

I am currently utilizing the Material UI library in combination with React and Typescript. Whenever I attempt to pass a conditional boolean as the "button" prop of the component, I encounter a typescript error stating: Type 'boolean' is not assi ...

Updating dynamically rendered component content with ngComponentOutlet in Angular 11: A comprehensive guide

I am working on an Angular 11 app that includes a menu generated from an array of objects with specific properties: { icon: CUSTOMER_ORDER_PROPERTIES.icon, iconColor: CUSTOMER_ORDER_PROPERTIES.color, label: 'Search Customer Order', routeB ...

Typescript Routing Issue - This call does not match any overloads

Need assistance with redirecting to a sign-up page upon button click. Currently encountering a 'no overload matches this call' error in TypeScript. Have tried researching the issue online, but it's quite broad, and being new to Typescript ma ...