Mikail G.
Mikail G.

Reputation: 478

Angular 2/4 two way data binding does not work in observable

Hi, I use a third party library simple-peer which I did declared declare var SimplePeer: any; in angular 4 , than the all logic of that is warped in navigator.n.mediaDevices.getUserMedia() (asking user for video/audio permission) which is asynchronous function and the problem is that SimplePeer returns some data that I need to use in my html but I can't output the data in my html only with console.log() , here is the code app.component.html:

<input type="text" [(ngModel)]="targetpeer">
<button (click)="connect()">Connect</button>
<button (click)="message()">Send Message</button>



<p>{{texttoken}}</p>





<video #myVideo></video>

ignore the video thing, everything works except that the {{texttoken}} is not updated, it displays the same initial dummy data that I set in my app.component.ts:

import { Component, OnInit, ViewChild } from '@angular/core';
import { Subject } from 'rxjs/Subject';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  @ViewChild('myVideo') myVideo:any; 

  texttoken :any = 'initial dummy value'; 
  targetpeer: any;
  peer: any;
  n = <any>navigator;

  ngOnInit() {


    let video = this.myVideo.nativeElement;
    let peerx: any;
    let onJSTokenChange = new Subject(); // create new observable to obsere any changes to assign a value to texttoken
    onJSTokenChange.subscribe((value)=>{

        this.texttoken = value;
        console.log(this.texttoken);

    });


    this.n.getUserMedia = (this.n.getUserMedia || this.n.webkitGetUserMedia || this.n.mozGetUserMedia || this.n.msGetUserMedia);
    this.n.mediaDevices.getUserMedia({video:true, audio:true}).then( function(stream) {
    peerx = new SimplePeer ({
      initiator: location.hash === '#init',
      trickle: false,
      stream:stream
    })

    peerx.on('signal', function(data) {
      console.log(JSON.stringify(data));
      // here I pass that data to the observable  
      onJSTokenChange.next(JSON.stringify(data));
      this.targetpeer = data;
    })

    peerx.on('data', function(data) {
      console.log('Recieved message:' + data);
    })

    peerx.on('stream', function(stream) {
      video.src = URL.createObjectURL(stream);
      video.play();
    })

    }, function(err){
    console.log('Failed to get stream', err);
    });










  }

  connect() {
    this.peer.signal(JSON.parse(this.targetpeer));
  }

  message() {
    this.peer.send('Hello world');
  }





}

here you can see that I assigned the dummy data to my texttoken , than I create an observable onJSTokenChange to track if something changes to assign a value to texttoken , this observable gets data from peerx.on('signal' code when ever it executes and then the onJSTokenChange.subscribe gets that data and console.log() the data which works as expected however the the.texttoken receives the value as well but it does not do the two-way binding and does not update <p>{{texttoken}}</p> even though I console.log() it and it returns the correct value , please help been trying to figure it out the whole day :(

Upvotes: 1

Views: 770

Answers (1)

Mikail G.
Mikail G.

Reputation: 478

I just imported ChangeDetectorRef from angular/core and injected

constructor(private detector:ChangeDetectorRef){}

used it in my

onJSTokenChange.subscribe((value)=>{

        this.texttoken = value;
         this.detector.detectChanges();

    });

and it worked, thanks to @AJT_82 and @LLai

Upvotes: 2

Related Questions