Imran
Imran

Reputation: 5642

How do I get a webcam working with AngularJS?

Previously I've put working webcam code into my application, but now it's not working when I updated to AngularJS v1.5.0. I am using webcam-directive which was working perfectly with v1.3.0.

Here is my code:

<webcam placeholder="selfiePlaceHolder"
  on-stream="onStream(stream)"
  on-access-denied="onError(err)" on-streaming="onSuccess(video)">
</webcam>

But now it's giving following error with AngularJS v1.5.0:

Uncaught Error: [$parse:isecdom] Referencing DOM nodes in Angular expressions is disallowed! Expression: onSuccess(video)
http://errors.angularjs.org/1.5.0/$parse/isecdom?p0=onSuccess(video)

I also tried to use a different solution with AngularJS ng-Camera but even its demo page is not working for me.

Note: I know the issue is that we can't access the DOM from the newer version of AngularJS, but the same code works with the older version. I need to know how to pass the "Video" DOM object to the controller.

Upvotes: 9

Views: 6123

Answers (3)

Imran
Imran

Reputation: 5642

I've found the solution to the problem. Two things need to be done:

First In HTML:

<webcam channel="channel" 
        on-streaming="onSuccess()" 
        on-error="onError(err)" 
        on-stream="onStream(stream)"></webcam>

Secondly, in the controller, you can access the DOM video with the following code:

 $scope.onSuccess = function () {
        // The video element contains the captured camera data
        _video = $scope.channel.video;
        $scope.$apply(function() {
            $scope.patOpts.w = _video.width;
            $scope.patOpts.h = _video.height;
            //$scope.showDemos = true;
        });
    };

Here is a working example.

Upvotes: 10

CShark
CShark

Reputation: 1622

I was able to get webcam-directive working using the channel suggestion from the comment above, based on the example on the github page.

function MyController($scope) {
    $scope.myChannel = {
        // the fields below are all optional
        videoHeight: 800,
        videoWidth: 600,
        video: null // Will reference the video element on success
    };
}

In the onSuccess(on-streaming attr) and onStream(on-stream attr) callback the video property of myChannel was filled in with the video DOM element (and then it would obviously be available to everything else in the controller too). According to the comment in the example code though, you should wait to access it at least until onSuccess. Here is a working example

Upvotes: 1

Eray Balkanli
Eray Balkanli

Reputation: 7960

It is a potential error generally occurs when an expression tries to access a DOM node since it is restricted accessing to DOM nodes via expressions by AngularJS because it might cause to execute arbitrary Javascript code.

The $parse:isecdom error is related to an invoke to a function by event handler when an event handler which returns a DOM node, like below:

<button ng-click="myFunction()">Click</button>
$scope.myFunction = function() {
  return DOM;
}

To fix this issue, avoid access to DOM nodes and avoid returning DOM nodes from event handlers. (Reference: https://docs.angularjs.org/error/$parse/isecdom)

Adding an explicit return might solve this issue as detailed here: CoffeeScript - Referencing DOM nodes in Angular expressions is disallowed

Upvotes: 3

Related Questions