panos
panos

Reputation: 49

AngularJS controller cannot store Youtube API response results to a variable

I'm trying to make a search request using youtube's API and store the result to a variable inside an AngularJS' controller.

This is my app.js file.

var app = angular.module('myApp', []);

app.controller('myController', ['$scope', function($scope){

    this.data = '###';

    this.search = function(){
        var request = gapi.client.youtube.search.list({
        part: 'snippet',
        q: 'beatles'
        });

        request.execute(function(response){
            var responseString = JSON.stringify(response, '', 2);
            this.data = responseString;
            // document.getElementById('response').innerHTML += this.data;
        });
    }

}]);

function onClientLoad() {
    gapi.client.load('youtube', 'v3', onYouTubeApiLoad);
}

function onYouTubeApiLoad() {
    gapi.client.setApiKey('blahblahblahblahblahblah');
}

and this is the index.html.

<!DOCTYPE html>

<html ng-app="myApp">
<head>
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" />
</head>
<body ng-controller="myController as c">
    <div ng-click="c.search()" class="btn btn-success">
        Press me!
    </div>
    <h2>Result</h2>
    <pre id="response"> {{c.data}} </pre>

</body>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
<script type="text/javascript" src="js/app.js"></script>
<script src="https://apis.google.com/js/client.js?onload=onClientLoad" type="text/javascript"></script>
</html>

In the html code, there is a press me button which invokes the search() function which makes the request. The javascript console shows that the request was executed successfully.

I store the response result to a variable called data. The problem is that the content of the variable does not change. However, if I store this value inside the .innerHTML of a document element (the classic Javascript way), this works, and the results are shown successfully (this line is currently commented out).

Why response result cannot be stored in a variable that lives outside this function?

Upvotes: 2

Views: 108

Answers (3)

panos
panos

Reputation: 49

Finally, the solution to the problem was a combination of the two answers above:

var app = angular.module('myApp', []);

app.controller('myController', ['$scope', '$q', function($scope, $q){

    var c = this;

    c.search = function(){
        var request = gapi.client.youtube.search.list({
        part: 'snippet',
        q: 'beatles'
        });

        request.execute(function(response){
            var responseString = JSON.stringify(response, '', 2);
            c.data = responseString;
            $scope.$digest();
        });

    };

}]);

we first need to set the controller itself to a variable with

var c = this;

and then we need to call $scope.$digest() as well to update the c.data value. Now right at the time the button is pressed, the result is shown in the page.

Upvotes: 0

Vaibhav
Vaibhav

Reputation: 569

I am assuming gapi.client is not an angular library. The request for search is concluded outside angularjs and hence angular doesn't update scope with new response. You will have to call the digest cycle in callback of request.execute. Something like the following should work:

request.execute(function(response){
        var responseString = JSON.stringify(response, '', 2);
        this.data = responseString;
        $scope.$digest();
    });

I hope this helps.

Upvotes: 0

Sampath
Sampath

Reputation: 65978

Please try like this.

app.controller('myController', ['$scope', function($scope){

  var c = this;

 c.search = function(){
        var request = gapi.client.youtube.search.list({
        part: 'snippet',
        q: 'beatles'
        });

        request.execute(function(response){
                    var responseString = JSON.stringify(response, '', 2);
                    c.data = responseString;
           });
    }

          console.log(c.data);

    }]);

Upvotes: 1

Related Questions