Charles Robertson
Charles Robertson

Reputation: 1820

How to overwrite a subscription

I have a situation where I need to place a subscription inside a function, which is called multiple times.

My question is, if I call the function 3 times, do I create 3 new subscriptions or does the original subscription get overwritten?

The reason behind this question, is that I want to avoid creating multiple subscriptions, so as not to cause a memory leak.

var observable = Rx.Observable;
var subscription = new Rx.Subscription();

var numbers = observable.from([1,2,3,4,5,6]);

function foo(){

    subscription = numbers.subscribe( val => console.log("numbers subscribes",val) )

    subscription.unsubscribe();

}

foo();
foo();
foo();

UPDATE:

I have been asked to display the actual code from my project. I have left out quite a lot of code for simplicty, but the references to:

this.messages

Refer to an observable that emits an array.

I want to remove this line safely:

this.subscriptionPostMessages.unsubscribe();

Here is the code:

import { Injectable, OnDestroy } from '@angular/core';
import { Subject, Observable, Subscription } from 'rxjs';
import { HttpClient, HttpHeaders, HttpEventType, HttpRequest, HttpErrorResponse, HttpEvent, HttpParams } from '@angular/common/http';

import { Message } from '../message/message.model';
import { GlobalsService } from '../globals/globals.service';
import { environment } from '../../environments/environment';

@Injectable()
export class MessagesService implements OnDestroy {

  messages: Observable<Message[]>;
  postMessages: Observable<Message[]>;

  subscriptionPostMessages: Subscription;

  constructor(public http: HttpClient,
              public globalsService: GlobalsService) {


  postMessage(message: Message): void {
    const body = {
      messageid: message.id,
      filename: ''
    };
    const requestHeaders = new HttpHeaders().set('Content-Type', 'application/json');
    const headers = {
      headers: requestHeaders
    };
    this.http.post(this.globalsService.baseUrl + environment.ajax_dir + '/ajax-ng-post-message-module.cfm', body, headers).map(
      (res: Response) => {
        if('filename' in res && res['filename'] !== ''){
          this.postMessages = this.addFileNameToMessage(res['messageid'], res['filename']);
          this.subscriptionPostMessages = this.postMessages.subscribe( (messages: Message[]) => {
          });
          this.subscriptionPostMessages.unsubscribe();
        }
        return res;
      })
      .subscribe();
  }

  addFileNameToMessage(id: string, filename: string): Observable<Message[]> {
    return this.messages.map( (messages: Message[]) => {
      messages.map( (message: Message) => {
        if(message.id === id){
          message.file.filename = filename;
          message.file.value = '';
        }
      })
      return messages;
    })
  }

  ngOnDestroy() {
    if (this.subscriptionPostMessages) {
      this.subscriptionPostMessages.unsubscribe();
    }
  }

}

Does:

this.subscriptionPostMessages

Get overwritten each time:

postMessage()

Gets called?

In other words, will I only ever have one subscription active at any one time?

Upvotes: 1

Views: 1746

Answers (1)

Mark van Straten
Mark van Straten

Reputation: 9425

If you invoke your code as supplied you will not have multiple subscriptions lingering around because you subscribe and unsubscribe in the same function call. Note that this will result in unexpected behaviour with regards to the amount of values you will receive in your onNext callback of the subscribe given the async nature of RxJs.

I have the feeling you are almost stumbling upon a rx-antipattern but you would need to give more information about what you want to archieve to give you a better answer about that.

Upvotes: 1

Related Questions