Timotronadon
Timotronadon

Reputation: 365

Service initializing once but not a second time

I just found a bug in my app I've been playing with that seems to make no sense to me.

Issue: I have two components on different MatTabs. Each is instantiating properly and being destroyed between tab changes. My Post service is returning an observable and populating my data table perfectly. So like a dumb kid, I go into my service and try to clean the code up a bit. After changing Post Service from:

     constructor(private afs: AngularFirestore, private router:Router, ) {
    this.postsCollection = afs.collection<Post>(config.collection_endpoint);

    this.posts = 
      this.afs.collection('posts').snapshotChanges()
      .pipe(map(actions => actions.map(this.documentToDomainObject)));
      }
     getPosts(){
    return  this.afs.collection('posts').snapshotChanges()
    .pipe(map(actions => actions.map(this.documentToDomainObject)));
   }

this works fine but im repeating myself so I decided to clean it up - changed it to:

constructor(private afs: AngularFirestore, private router:Router, ) {
    this.postsCollection = afs.collection<Post>(config.collection_endpoint);

    this.posts = 
      this.afs.collection('posts').snapshotChanges()
      .pipe(map(actions => actions.map(this.documentToDomainObject)));}
     getPosts(){
    return this.posts;}

after changing the code I only get one instance of this that populates. Is there a reason that this is happening? To me this is the same code and I know theres something here I'm not understanding but I can't for the life of me find out what it is. Is there something in the way services are instantiated that I'm not seeing here? Thanks again.

heres feed.component in case you need that too. Sorry in advance for the spacing I can't seem to post code here properly.

export class FeedComponent implements OnInit, 
    OnChanges, OnDestroy {
    postData: Post[] = [];
    subDepartmentSelections: string[] = []
    filteredData: any[] = []
    dataReady: boolean = false;
    dataSource: MatTableDataSource<any> = new 
       MatTableDataSource;
    displayedColumns: string[] = ['User', 'Title', 
    "Description", "Date Available", "Contact"]

    posts = this.ps.getPosts();

    currentDepartment: string = ""
    constructor(private ps: PostService, public dialog: 
    MatDialog, public change: ChangeDetectorRef, public 
    ms: MessageService) {}
    ngOnInit() {
    this.refreshPosts()
    console.log("this is refreshing and data ready = " + this.dataReady)
  }

    refreshPosts() {

    this.posts.subscribe(posts => {

      this.dataReady = false;
      this.postData = posts.filter(post =>
        post.uid != `${this.currentUser.uid}` &&
        post.claimedBy != `${this.currentUser.uid}`);
        this.dataSource = new 
        MatTableDataSource(this.postData)
        this.dataSource.paginator = this.paginator;
        this.dataSource.sort = this.sort
        this.dataReady = true;
        console.log("this is refreshing and data ready = " + this.dataReady)
     });

Upvotes: 0

Views: 835

Answers (1)

seawave_23
seawave_23

Reputation: 1248

Depending on where you provide your service, it is instantiated. This means, you can have a singleton service by using this in the service:

@Injectable(){
providedIn: 'root'
}

or by adding it as a dependency to one single module's "providers" array.

But to have it reinstantiated every time freshly when using it in a component, you should maybe provide it on component level:

@Component({
 selector: 'your-component',
 template: `...`,
 providers: [ NonSingletonService]
})

Upvotes: 0

Related Questions