angularobservable

After assinging data to a variable in a subscribe methode, the data is gone once the method is done


I'm using the library signature_pad and if I draw a line, the method toDataURL() gives back a string. I've got a MessagingService where I have a method to send a string between unrelated Angular components. The idea is to assign the datastring to the img src. When I hardcode a previous dataURL into my PdfPageComponent the line I drawed shows up. However, when I try to send the data with my messageService something goes wrong. When I console log the message, I can see the string is send over correctly. The problem is when I try to assign that data to the variable signatureImg. Once again when I assign it, the console.log() tells me it's good. But when I click on my onShowSignatureButtonClick() the string is gone, and I'm getting a undefined. I realise its probably an issue with Observables and the 'waiting' period. I already googled it and tried a bunch of things I found here, but nothing seems to work.

This is the PDF page, in here the signatureImg string should be the string I'm getting from my MessagingService

import { Component, OnInit, SimpleChanges, OnChanges } from '@angular/core';
import { MessagingService } from '../messaging.service';
import { Observable } from 'rxjs';

@Component({
  selector: 'app-pdf-page',
  templateUrl: './pdf-page.component.html',
  styleUrls: ['./pdf-page.component.scss']
})
export class PdfPageComponent implements OnInit {

  signatureImg: string;
  constructor(private _messaging: MessagingService) { }

  ngOnInit() {
    this._messaging.signatureDataUrl$
      .subscribe((message) => {
        this.signatureImg = message;
        // console.log(this.signatureImg, "signatureImg in subscribe onint");
      });
  }

  onShowSignatureButtonClick() {
    console.log(this.signatureImg, "signatureImg"); //Gives undefined
  }
}

This is my MessagingService, in here I got the sendDataUrl() which is responsible for sending the string.

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

@Injectable({
  providedIn: 'root'
})
export class MessagingService {

  private signatureDataUrlSource = new Subject<string>();
  signatureDataUrl$ = this.signatureDataUrlSource.asObservable();

  constructor() { }

  sendDataUrl(dataUrl: string) {
    return this.signatureDataUrlSource.next(dataUrl);
  }

}

This is the page where somebody can draw something using the signature_pad library.

import { Component, OnInit, ViewChild } from '@angular/core';
import { SignaturePad } from 'angular2-signaturepad/signature-pad';
import { Router } from '@angular/router'
import { MessagingService } from '../messaging.service';

@Component({
  selector: 'app-sign-page',
  templateUrl: './sign-page.component.html',
  styleUrls: ['./sign-page.component.scss']
})
export class SignPageComponent implements OnInit {

  @ViewChild(SignaturePad, {static: false}) 
  signaturePad: SignaturePad
  signatureImg: any;

  private signaturePadOptions: Object = { // passed through to szimek/signature_pad constructor
    'minWidth': 5,
    'canvasWidth': 500,
    'canvasHeight': 300,
  };
  constructor(private router: Router, private _messaging: MessagingService) { }

  ngOnInit() {
  }

  confirmSignature(){
    this.signatureImg = (this.signaturePad.toDataURL())
    this._messaging.sendDataUrl(this.signaturePad.toDataURL().toString());
    this.router.navigateByUrl("/pdfpage");
}

//Rest of the code


Solution

  • private signatureDataUrlSource = new Subject<string>();
    

    Try using a behavior subject

    private signatureDataUrlSource = new BehaviorSubject<string>(undefined);
    

    It might be because your subject is subscribed after you send it a value : if it's the case, then the behavior subject will resolve it.