I'm using getUserMedia to get an audio stream. The audio stream is only available in the callback from getUserMedia. However, when I try to update the bindings from inside the callback, angular doesn't detect the changes and doesn't update the bindings. I've tried to use $scope.$apply as suggested by many articles, but it doesn't seem to do anything.
Here is a fiddle that shows what I've tried. http://jsfiddle.net/poptart911/a00koc8r/1/
angular.module('test', [])
.controller('mainController', function ($scope) {
this.deviceStatus = "Angular works.";
this.deviceStatus = "We can update a binding.";
navigator.mediaDevices.getUserMedia({
audio: true,
video: false
}).then(function (stream) {
this.deviceStatus = "Angular doesn't detect this change.";
$scope.$apply(function (stream) {
this.deviceStatus = "I even tried scope.apply!";
alert("But I know this code is executing");
});
});
});
$scope.$apply
is working as expected. However, the scope of this
refers to the scope of the inner lambda function, not the scope of the outer function where deviceStatus
is first declared. As a result, the getUserMedia
callback creates a new deviceStatus
variable instead of altering the original variable (to which the UI is bound). Try storing a reference to the original this
and use it when referencing deviceStatus
in your inner lambda function:
angular.module('test', [])
.controller('mainController', function ($scope) {
var that = this;
that.deviceStatus = "Angular works.";
that.deviceStatus = "We can update a binding.";
navigator.mediaDevices.getUserMedia({
audio: true,
video: false
}).then(function (stream) {
that.deviceStatus = "*Now* angular detects this change.";
$scope.$apply(function (stream) {
that.deviceStatus = "I even tried scope.apply!";
alert("But I know this code is executing");
});
});
});
Here's a working jsfiddle as a demonstration. The getUserMedia
function has been replaced with a setTimeout
since that function didn't seem to be working for me.