Angular + rxjs: No provider for Subscription

Viewed 9300

I'm trying to implement a service-component communication in angular, when service holds a value and component subscribes to it change. I'm using rxjs Subscription, but I'm getting

Uncaught (in promise): Error: No provider for Subscription!

Here is what I'm doing in a service:

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

@Injectable()
export class PracticeContextService {
  practice: Subject<any> = new Subject<any>();
  public practiceSelected$ = this.practice.asObservable();

 setPractice(providerId: string) {
   this.practice.next({ providerId: providerId });
 }

 getPractice(): Observable<any> {
   return this.practice.asObservable();
 }
}

and in the component:

import { Component, OnDestroy, OnInit } from '@angular/core';
import { Subscription } from 'rxjs/Subscription';
import { PracticeContextService } from '../practice-context.service';

@Component({
  selector : 'practice-context-selector',
  templateUrl : './practice-context-selector.component.html',
  styleUrls : ['./practice-context-selector.component.css']
})

export class PracticeContextSelectorComponent implements OnInit, OnDestroy {

  practice: string;

  constructor(private context: PracticeContextService,
          private subscription: Subscription) {}

  ngOnInit() {
    this.subscription = this.context.practiceSelected$.subscribe(
      practice => {
        this.practice = practice;
      });
  }

  ngOnDestroy() {
    this.subscription.unsubscribe();
  }
}

Component and service are than bundled into module, which is later injected into another module.

import { NgModule }           from '@angular/core';
import { CommonModule }       from '@angular/common';

import { PracticeContextSelectorComponent } from './practice-context-selector/practice-context-selector.component';
import { PracticeContextService } from './practice-context.service';

@NgModule({
  imports : [
    CommonModule
  ],
  declarations : [
    PracticeContextSelectorComponent
  ],
  providers : [
    PracticeContextService,
  ],
  exports: [
    PracticeContextSelectorComponent
  ]
})

export class PracticeContextModule {}

Apparently, I'm doing something wrong here

5 Answers

Just remove private subscription: Subscription from constructor and put it in attribute of the class.

In your service, you could first of all change rxjs imports like this :

import { Observable, Subscription } from 'rxjs/Rx';

I already had an issue when importing { Observable } from 'rxjs/Observable'. Now I am careful with this :P ! (I should maybe dig further to find out what really happens behind the scene.)

Then, as already said Lyubimov Roman in its comment above, you should not import rxjs subscription through the constructor. I don't understand your answer to Lyubimov's comment. Could you please provide us the examples you mention in order to let us figure out what is intended ?

If you need to use an subscription object in your component, just import it like this :

import { Subscription } from 'rxjs/Rx';

Remove it from constructor and declare it out side.

private _Subscription: Subscription;

  constructor() {
  }

Even when I was new to angular and faced this issue multiple times and couldn't understand what the issue was. So to start with make sure you have the imports properly declared as import { Observable, Subscription } from 'rxjs';

For me the error was Null Injection Error. No Provider for Subscription.

Initially, I started declaring the Subscription inside the constructor as :

constructor(){private activatedsubscription:Subscription}

This wouldn't work, as I later realized that the reason why it was Null Injection, was because it was declared inside the constructor, where as it should be declared outside the constructor as a property or Globally inside the Class as:

export class Component implements OnInit{
activatedsubscription:Subscription
}

Note: Make sure that you unsubscribe the from the Subscription when destroying the Component by calling OnDestroy. Otherwise you would have memory leak.

i was started with make sure you have the imports properly declared as

import { Subscription } from 'rxjs'

then i use it as

public subscription : Subscription = new Subscription();
Related