Reputation: 326
I am currently developing an angular7-app, created it the standard way through CLI and started coding.
Now I would like to record some audio which is no difficult thing in modern browsers. I am using the built-in browser functionalities of getUserMedia()
.
Now comes the problem: zone.js catches all calls to the then()
callback and does not allow to execute the custom code inside.
BUT: There is the patch delivered with zone.js, so that this special callback is called: https://github.com/angular/zone.js/blob/master/dist/zone-patch-user-media.js
Unfortunately, this refers to a depreciated implementation of getUserMedia()
(https://developer.mozilla.org/en-US/docs/Web/API/Navigator/getUserMedia).
So this script does not work. I tried changing it but nothing works. The patch is called because console.log()
is displayed and in the debugger, I can go through the function. I assume, that this might be a little change to execute the callback. In the debugger the callback is then again catched by a function in zone.js which, as I assume, should not be called when the patch works. My implementation is the same as here (https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia):
navigator.mediaDevices.getUserMedia(constraints).then(
function(stream) {
/* use the stream */
}).catch(
function(err) {
/* handle the error */
});
So, what is the current way of getting the callback to work? Or am I getting the concept wrong? Or should I use some library from npm to record the audio?
Upvotes: 2
Views: 3899
Reputation: 10444
As much as I know, zone.js
should not cause problems if used with navigator
methods, since they're well known and correctly patched. By the way, if you are sure of what you say, you can still use zone.runOutsideAngular
to go out from a zone:
constructor(private zone: NgZone) { }
yourMethod() {
this.zone.runOutsideAngular(() => {
navigator.mediaDevices.getUserMedia(constraints)
.then(stream => console.log(stream))
.catch(err => console.error(err));
});
}
If then you want to re-enter a zone, you can call:
this.zone.run(() => {
// again inside a zone
});
But be aware that you need it only if you want to continue an async flow. The sync code will keep being executed inside a zone:
yourMethod() {
// this is inside a zone
this.zone.runOutsideAngular(() => {
navigator.mediaDevices.getUserMedia(constraints)
.then(stream => {
// this is outside a zone
this.zone.run(() => {
// and again inside a zone
});
})
.catch(err => console.error(err));
});
// this is still inside a zone
}
Upvotes: 4