Kate Sowles
Kate Sowles

Reputation: 113

Why isn't my singleton service accessible?

I'm currently using Angular 4.4.6 and I've got a number of singleton services in my app, all of which are imported via my AppModule> The issue arises with one particular service that requires the inclusion of providers: [ ViewService ] importing components' metadata and I'm losing my mind trying to figure out why it's not accessible without the providers declaration like the rest of my services.

To provide a bit of context, here's the offending ViewService's :

import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import { Transition } from '@uirouter/angular';

@Injectable()
export class ViewService {
  constructor (
    public http: Http,
    public transition: Transition,
  ) {}

  ... service methods ...

}

And my service imports and declarations inside my app.module.ts:

import { ContactService } from './_services/contact.service';
import { ErrorService } from './_services/error.service';
import { OrganizationService } from './_services/organization.service';
import { ProjectService } from './_services/project.service';
import { TokenService } from './_services/token.service';
import { UserService } from './_services/user.service';
import { ViewService } from './_services/view.service';  <-- offending service

@NgModule({
  imports : [ ... ],
  declarations : [ ... ],
  providers: [
    ContactService,
    ErrorService,
    OrganizationService,
    ProjectService,
    TokenService,
    UserService,
    ViewService,  <-- offending service
  ],
  bootstrap : [ UIView ],
  entryComponents: [ ... ]
})

export class AppModule {}

And in terms of how the ViewService is imported into components, here's one example:

import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, Validators, FormsModule, ReactiveFormsModule } from '@angular/forms';
import { Transition } from '@uirouter/angular';

import { ProjectService } from '../../_services/project.service';
import { ViewService } from '../../_services/view.service';  <-- offending service

@Component({
  selector: 'create-project',
  templateUrl: './create_project.component.html',
  providers: [ ViewService ]   <-- offending service MUST be included in providers, but no other services require this —- but I want it to serve as singleton service, same as the rest of my services.
})

export class CreateProjectComponent implements OnInit {

  ... component variables ...

  constructor (
    public formBuilder: FormBuilder,
    public transition: Transition,

    public projectSvc: ProjectService,
    public viewSvc: ViewService,  <-- offending service
  ) {}

  ... component methods ...

}

And the error that's returned:

Error: No provider for t!

So far as I can tell, there are no differences between my ViewService and my other services in terms of metadata/structure/boilerplate/import method.

Has anyone come across this? Have any ideas for how I might at least debug this further?

Thank you in advance!

UPDATE: here is the full app.module.ts file:

// third-party libraries/modules
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { HttpModule, JsonpModule } from '@angular/http';
import { BrowserModule } from '@angular/platform-browser';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { UIRouterModule, UIView } from '@uirouter/angular';
import { DragulaModule } from 'ng2-dragula';

// necessary boot/root elements
import { APP_STATES } from './app.states';
import { routerConfigFn } from './router.config';

// pipes
import { SortAscendPipe } from './_pipes/sort_ascend.pipe';

// custom modules
import { ColumnSortModule } from './sortable_column/sortable_column.module';
import { MultiselectInputModule } from './multiselect_input/multiselect_input.module';

// services
import { AccountContactService } from './_services/account_contact.service';
import { ActivitiesService } from './_services/activities.service';
import { ArchiveService } from './_services/archive.service';
import { ContactService } from './_services/contact.service';
import { DistributionListService } from './_services/distribution_list.service';
import { DragDropService } from './_services/drag_drop.service';
import { ErrorService } from './_services/error.service';
import { NoAuthService } from './_services/no_auth.service';
import { OrganizationService } from './_services/organization.service';
import { ProjectService } from './_services/project.service';
import { SalesforceService } from './_services/salesforce.service';
import { TokenService } from './_services/token.service';
import { UserService } from './_services/user.service';
import { ViewService } from './_services/view.service';

import { InvalidLinkComponent } from './noauth_invalid_link/invalid_link.component';
import { LoginComponent } from './noauth_login/login.component';
import { NoAuthComponent } from './no_auth.component';
import { RedirectCounterComponent } from './noauth_invalid_link/redirect_counter/redirect_counter.component';
import { ResetRequestComponent } from './noauth_reset_request/reset_request.component';
import { SetPasswordComponent } from './noauth_set_password/set_password.component';

// components
import { AppComponent } from './app.component';
import { ArchiveActionsComponent } from './actions/actions_archive/actions_archive.component';
import { ArchiveImportComponent } from './forms_create/create_contact/archive_import/archive_import.component';
import { ArchiveContactComponent } from './archive_detail/archive_contact/contact.component';
import { ArchiveItemComponent } from './archive_list/archive_item/archive_item.component';
import { ArchiveListComponent } from './archive_list/archive_list.component';
import { ArchiveOrgComponent } from './archive_detail/archive_organization/organization.component';
import { ArchiveProjectComponent } from './archive_detail/archive_project/project.component';
import { ArchiveDivisionComponent } from './archive_detail/archive_division/division.component';
import { AuditTrailComponent } from './audit_trail/audit_trail.component';
import { AuditTrailConfirmAlertComponent } from './modal/alerts/audittrailconfirm_alert/audittrailconfirm_alert.component';
import { AuditTrailConfirmTrigger } from './modal/triggers/audittrailconfirm_alert.modal';
import { CirculateProjectComponent } from './forms_circulate/circulate_project/circulate_project.component';
import { ContactActionsComponent } from './actions/actions_contact/actions_contact.component';
import { CreateContactComponent } from './forms_create/create_contact/create_contact.component';
import { CreateDistListComponent } from './forms_create/create_distlist/create_distlist.component';
import { CreateOrganizationComponent } from './forms_create/create_organization/create_organization.component';
import { CreateOrganizationTrigger } from './modal/triggers/create_organization.modal';
import { CreateProjectComponent } from './forms_create/create_project/create_project.component';
import { CsvImportComponent } from './forms_create/create_contact/csv_import/csv_import.component';
import { CsvImportFailuresAlertComponent } from './modal/alerts/csvimportfail_alert/csvimportfail_alert.component';
import { CsvImportFailuresTrigger } from './modal/triggers/csvimportfail_alert.modal';
import { CurrentProjectsComponent } from './navigation_project/currentprojects/currentprojects.component';
import { CurrentProjectsItemComponent } from './navigation_project/currentprojects/currentprojects_item/currentprojects_item.component';
import { DatabaseImportComponent } from './forms_create/create_contact/db_import/db_import.component';
import { DbImportFailuresAlertComponent } from './modal/alerts/dbimportfail_alert/dbimportfail_alert.component';
import { DbImportFailuresTrigger } from './modal/triggers/dbimportfail_alert.modal';
import { DeletionAlertComponent } from './modal/alerts/deletion_alert/deletion_alert.component';
import { DeletionAlertTrigger } from './modal/triggers/deletion_alert.modal';
import { DistListActionsComponent } from './actions/actions_distlist/actions_distlist.component';
import { DistlistContactComponent } from './distlist_detail/distlist_contact/contact.component';
import { DistlistOrgComponent } from './distlist_detail/distlist_organization/organization.component';
import { DistlistProjectComponent } from './distlist_detail/distlist_project/project.component';
import { DistlistDivisionComponent } from './distlist_detail/distlist_division/division.component';
import { DuplicateEmailAlertComponent } from './modal/alerts/duplicateemail_alert/duplicateemail_alert.component';
import { DuplicateEmailAlertTrigger } from './modal/triggers/duplicateemail_alert.modal';
import { EditContactComponent } from './forms_edit/edit_contact/edit_contact.component';
import { EditDistListComponent } from './forms_edit/edit_distlist/edit_distlist.component';
import { EditOrganizationComponent } from './forms_edit/edit_organization/edit_organization.component';
import { EditOrganizationTrigger } from './modal/triggers/edit_organization.modal';
import { EditProjectComponent } from './forms_edit/edit_project/edit_project.component';
import { ExportArchiveToActiveComponent } from './export_archivetoactive/export_archivetoactive.component';
import { IconsArchive } from './icons/export_archive/export_archive.component';
import { IconsAssistant } from './icons/assistant/assistant.component';
import { IconsBounced } from './icons/bounced/bounced.component';
import { IconsCirculate } from './icons/circulate/circulate.component';
import { IconsContactDigest } from './icons/contact_digest/contact_digest.component';
import { IconsContactPermission } from './icons/contact_permission/contact_permission.component';
import { IconsEditContact } from './icons/edit_contact/edit_contact.component';
import { IconsEditOrganization } from './icons/edit_organization/edit_organization.component';
import { IconsEditProject } from './icons/edit_project/edit_project.component';
import { IconsExportDoc } from './icons/export_doc/export_doc.component';
import { IconsExportPdf } from './icons/export_pdf/export_pdf.component';
import { IconsInvited } from './icons/invited/invited.component';
import { IconsManageLogos } from './icons/manage_logos/manage_logos.component';
import { IconsNoDocDistribution } from './icons/no_doc_distribution/no_doc_distribution.component';
import { IconsNoneditableBody } from './icons/noneditable_body/noneditable_body.component';
import { IconsNoneditableContact } from './icons/noneditable_contact/noneditable_contact.component';
import { IconsOneOrgImport } from './icons/one_org_import/one_org_import.component';
import { IconsPhoneFormat } from './icons/phone_format/phone_format.component';
import { IconsPrint } from './icons/export_print/export_print.component';
import { IconsProjectOwnership } from './icons/project_ownership/project_ownership.component';
import { IconsReviewPermissions } from './icons/review_permissions/review_permissions.component';
import { IconsSetPassword } from './icons/set_password/set_password.component';
import { IconsToEditContact } from './icons/toedit_contact/toedit_contact.component';
import { IconsToEditOrganization } from './icons/toedit_organization/toedit_organization.component';
import { IconsToEditProject } from './icons/toedit_project/toedit_project.component';
import { InvalidProjectAlertComponent } from './modal/alerts/invalid_project/invalid_project.component';
import { InvalidProjectAlertTrigger } from './modal/triggers/invalid_project.modal';
import { LogoManagementComponent } from './logo_management/logo_management.component';
import { ManualCreateComponent } from './forms_create/create_contact/manual/manual.component';
import { NestedContactComponent } from './nested_detail/nested_contact/contact.component';
import { NestedOrganizationComponent } from './nested_detail/nested_organization/organization.component';
import { NestedProjectComponent } from './nested_detail/nested_project/project.component';
import { NestedDivisionComponent } from './nested_detail/nested_division/division.component';
import { NotAllowedComponent } from './not_allowed/not_allowed.component';
import { PreArchiveComponent } from './forms_create/create_archive/create_archive.component';
import { PrintHtmlBaseTemplateComponent } from './templates/print_html/template_base.component';
import { ProjectActionsComponent } from './navigation_project/projectactions/projectactions.component';
import { ProjectNavigationComponent } from './navigation_project/navigation_project.component';
import { RelationshipSearchComponent } from './relationship_search/relationship_search.component';
import { RelationshipViewComponent } from './relationship_view/relationship_view.component';
import { SalesforceImportComponent } from './forms_create/create_contact/salesforce_import/salesforce_import.component';
import { SalesforceImportConfirmAlertComponent } from './modal/alerts/salesforce_import_confirm/salesforce_import_confirm.component';
import { SalesforceImportConfirmTrigger } from './modal/triggers/salesforce_import_confirm.modal';
import { SiteBannerComponent } from './navigation_site/site_banner/site_banner.component';
import { SiteNavigationComponent } from './navigation_site/navigation_site.component';
import { UserLogoComponent } from './navigation_site/userlogo/userlogo.component';
import { UserSettingsComponent } from './settings_user/settings_user.component';
import { VcardImportComponent } from './forms_create/create_contact/vcard_import/vcard_import.component';
import { ViewErrorsComponent } from './view_errors/view_errors.component';
import { WelcomeComponent } from './welcome/welcome.component';
import { WrongStatusAlertComponent } from './modal/alerts/wrong_status/wrong_status.component';
import { WrongStatusAlertTrigger } from './modal/triggers/wrong_status.modal';

@NgModule({
  imports : [ // third party libraries/modules go here
    CommonModule,
    NgbModule.forRoot(),
    FormsModule,
    ReactiveFormsModule,
    HttpModule,
    JsonpModule,
    BrowserModule,
    UIRouterModule.forRoot({
      states: APP_STATES,
      useHash: true,
      otherwise: { state: 'invalidLink' },
      config: routerConfigFn,
    }),
    DragulaModule,

    ColumnSortModule,
    MultiselectInputModule,
  ],
  declarations : [ // all custom components go here
    // pipes
    SortAscendPipe,

    InvalidLinkComponent,
    LoginComponent,
    NoAuthComponent,
    RedirectCounterComponent,
    ResetRequestComponent,
    SetPasswordComponent,

    // components
    AppComponent,
    ArchiveActionsComponent,
    ArchiveImportComponent,
    ArchiveContactComponent,
    ArchiveItemComponent,
    ArchiveListComponent,
    ArchiveOrgComponent,
    ArchiveProjectComponent,
    ArchiveDivisionComponent,
    AuditTrailComponent,
    AuditTrailConfirmAlertComponent,
    AuditTrailConfirmTrigger,
    CirculateProjectComponent,
    ContactActionsComponent,
    CreateContactComponent,
    CreateDistListComponent,
    CreateOrganizationTrigger,
    CreateOrganizationComponent,
    CreateProjectComponent,
    CsvImportComponent,
    CsvImportFailuresAlertComponent,
    CsvImportFailuresTrigger,
    CurrentProjectsComponent,
    CurrentProjectsItemComponent,
    DatabaseImportComponent,
    DbImportFailuresAlertComponent,
    DbImportFailuresTrigger,
    DeletionAlertComponent,
    DeletionAlertTrigger,
    DistListActionsComponent,
    DistlistContactComponent,
    DistlistOrgComponent,
    DistlistProjectComponent,
    DistlistDivisionComponent,
    DuplicateEmailAlertComponent,
    DuplicateEmailAlertTrigger,
    EditContactComponent,
    EditDistListComponent,
    EditOrganizationComponent,
    EditOrganizationTrigger,
    EditProjectComponent,
    ExportArchiveToActiveComponent,
    IconsArchive,
    IconsAssistant,
    IconsBounced,
    IconsCirculate,
    IconsContactDigest,
    IconsContactPermission,
    IconsEditContact,
    IconsEditOrganization,
    IconsEditProject,
    IconsExportDoc,
    IconsExportPdf,
    IconsInvited,
    IconsManageLogos,
    IconsNoDocDistribution,
    IconsNoneditableBody,
    IconsNoneditableContact,
    IconsOneOrgImport,
    IconsPhoneFormat,
    IconsPrint,
    IconsProjectOwnership,
    IconsReviewPermissions,
    IconsSetPassword,
    IconsToEditContact,
    IconsToEditOrganization,
    IconsToEditProject,
    InvalidProjectAlertComponent,
    InvalidProjectAlertTrigger,
    LogoManagementComponent,
    ManualCreateComponent,
    NestedContactComponent,
    NestedOrganizationComponent,
    NestedProjectComponent,
    NestedDivisionComponent,
    NotAllowedComponent,
    PreArchiveComponent,
    PrintHtmlBaseTemplateComponent,
    ProjectActionsComponent,
    ProjectNavigationComponent,
    RelationshipSearchComponent,
    RelationshipViewComponent,
    SalesforceImportComponent,
    SalesforceImportConfirmAlertComponent,
    SalesforceImportConfirmTrigger,
    SiteBannerComponent,
    SiteNavigationComponent,
    UserLogoComponent,
    UserSettingsComponent,
    VcardImportComponent,
    ViewErrorsComponent,
    WelcomeComponent,
    WrongStatusAlertComponent,
    WrongStatusAlertTrigger,
  ],
  providers: [ // services go here
    AccountContactService,
    ActivitiesService,
    ArchiveService,
    ContactService,
    DistributionListService,
    DragDropService,
    ErrorService,
    NoAuthService,
    OrganizationService,
    ProjectService,
    SalesforceService,
    TokenService,
    UserService,
    ViewService
  ],
  bootstrap : [ // root component goes here
    UIView
  ],
  entryComponents: [
    CreateOrganizationTrigger,
    CreateOrganizationComponent,
    EditOrganizationTrigger,
    EditOrganizationComponent,
    DeletionAlertTrigger,
    DeletionAlertComponent,
    CsvImportFailuresAlertComponent,
    CsvImportFailuresTrigger,
    DbImportFailuresAlertComponent,
    DbImportFailuresTrigger,
    AuditTrailConfirmAlertComponent,
    AuditTrailConfirmTrigger,
    DuplicateEmailAlertComponent,
    DuplicateEmailAlertTrigger,
    InvalidProjectAlertComponent,
    InvalidProjectAlertTrigger,
    WrongStatusAlertComponent,
    WrongStatusAlertTrigger,
    SalesforceImportConfirmAlertComponent,
    SalesforceImportConfirmTrigger
  ]
})

export class AppModule {}

Upvotes: 0

Views: 101

Answers (1)

Ludevik
Ludevik

Reputation: 7264

The Transition dependency is not available in root injector. It is only available at component level injector when uirouter navigates to that component, that's why it works when you provide ViewService at component level.

I don't know why ViewService needs Transition dependency, but maybe TransitionService would fit the need.

Upvotes: 1

Related Questions