Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Update AngularJS scope from 3rd party library aynchronous callback

Hi I am trying to use import.io to scrape some football scores. I managed to get their JS to work with the API and deliver the data. The problem is it must be in a private scope inside the controller as I cannot do an ng-repeat on it.

Can anyone tell me why, and also if anyone has a good guide on Scope that would probably be more useful.

latestScores.controller('ScoresController', function ($scope) {
  $scope.pots = [];
  var io2 = new importio("XXX", "XXXXXX[API KEY]XXXXXXXX", "import.io");


    io2.connect(function (connected) {

        if (!connected) {
            console.error("Unable to connect");
            return;
        }


        var data;


        var callback = function (finished, message) {

            if (message.type == "DISCONNECT") {
                console.error("The query was cancelled as the client was disconnected");
            }

            if (message.type == "MESSAGE") {
                if (message.data.hasOwnProperty("errorType")) {

                    console.error("Got an error!", message.data);
                } else {
                    data = message.data.results;
                }
            }
            if (finished) {

                pots = data;
                console.log(pots); /* This gives me an object */
        }
       }
      io2.query({
      "connectorGuids": [
      "d5796d7e-186d-40a5-9603-95569ef6cbb9"],
    }, callback);
  });
     console.log($scope.pots); /* This gives me nothing */
});
like image 458
craigie2204 Avatar asked Apr 29 '15 09:04

craigie2204


2 Answers

angularjs data binding cannot know when you update your scope in a callback from a third party library.

In your callback, do this:

$scope.pots = dataReceived
$scope.$apply();

If you want to skip calling $scope.apply(), you need to use angular own promise module (called $q) and wrap your apis calls into a service.

Also, if your API is websocket based, you should subscribe to the $scope.on('$destroy') event to disconnect from your api when the controller is gone.

like image 57
Eloims Avatar answered Oct 12 '22 23:10

Eloims


ng-repeat has it's own scope. In your case your assigning data to the local variable instead of assigning it to the scope variabe.

change this piece of code

if (finished) {

                pots = data;
                console.log(pots); /* This gives me an object */
        }

to

if (finished) {

                $scope.pots = data;
                console.log($scope.pots); /* This gives me an object */
        }
like image 27
Ritt Avatar answered Oct 13 '22 00:10

Ritt