6

I've written a small JS library for Serial communication in a Chrome app, and it works fine on its own. However, we're running into a problem in integration with Angular: I don't have a way to watch a property of the serial object outside the controller from inside, and I have not been able to find a workaround. Ideally, there's a solution that isn't too computationally expensive, bu at this point, I am not ruling out some way to convert the entire library to a more Angular-friendly format. However, in this situation I'm not sure whether it should go in a service or some other format. Any help would be appreciated.

3 Answers 3

7

Just borrowed the idea from here: In AngularJS, how do I add a $watch on the URL hash?

$scope.$watch accepts function as the first argument, so you can do this:

$scope.$watch(function () {
    return mylib.myproperty
}, function (value) {
    // do stuff
});

UPDATE: As noted in the comments, when mylib.myproperty changes the controller won't know about it until the next digest cicle. Since mylib is not angular-enabled you need to use a plain javascript callback mechanism:

mylib.on_myproperty_change(function(){
    $scope.$digest(); // this will cause the $watch to be re-evaluated
});

But since now you already have a mylib.on_myproperty_change you don't really need to $watch anything, so you can delete the watch and just

mylib.on_myproperty_change(function(){
    //do the stuff that you did in the the $watch
    $scope.$digest(); 
});
Sign up to request clarification or add additional context in comments.

5 Comments

+1; although doesn't this add a "global dependency' to the controller, which is universally considered a bad thing from a unit testing perspective?
The callback will only be called when something causes a digest cycle. If the user/app is not interacting with the angular part of the app and changes mylib.myproperty, you won't be notified.
As @Sylvain said, my concern with this is that I would like dynamic updates without user interaction. Is there any way I can achieve this?
You guys are right. I think there's a good way to solve this problem though. I'll update the answer.
@TonyLâmpada @Sylvain Can someone elaborate on the answer above? what exactly is on_myproperty_change ? I too have an global object I need to track changes for inside a controller and am not able to get $watch to evaluate things when the global obj.property is changed.
2

Create your own custom library as an Angular service:

myAngularApp.service('MyCustomLib', function(){
    return myCustomLibInstance;
    }]
);

Then you can pass it into a controller and save it to the local scope:

function MyCtrl($scope,MyCustomLib) {
  var myCustomLib = MyCustomLib;

And now you have access to your custom library from inside the controller and you can set up a watch, as @tony had suggested in his answer:

$scope.$watch(
function () { 
  return myCustomLib.property 
}, 
function (newValue, oldValue) { 
 // do stuff 
});

Comments

0

The method I use to kick off a digest cycle is $timeout(function () {}).

$scope.$digest() will throw an error if there is already an existing digest cycle running.

I have it as

// From my controller
externalService.setOnChangeCallback(function () { $timeout(function () {}) });

// in my service
// on change event
this.onChangeCallBack();

$scope.$watch didn't reliably run for me. Sometimes the watched value was re-evaluated, sometimes it was not.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.