1

I am developing a single page application which retrieves blog feeds from a website. I got JSON using jQuery AJAX, and assigned the value to the "$scope.entries" variable, but its not reflecting the changes in View.

Since AngularJS is a two way data binding I guess the data must be binded automatically,

Here is the code,

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular-resource.min.js"></script>
    <script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
    <script>
        var myApp = angular.module("myApp", []);
        myApp.controller('picCtrl', function ($scope, myservice) {
            $scope.entries = [];
            $scope.message = "Welcome";

            myservice.jsonNews().then(loadData);
            function loadData(data) {
                //Data Loaded from AJAX Call
                debugger;
                console.log(data);
                angular.forEach(data.entry, function (entryX) {
                    $scope.entries.push(entryX);
                })
            };
        });

        myApp.service('myservice', function ($http, $q) {
            return ({
                jsonNews: jsonNews
            });
            function jsonNews() {
                var BlogFeeds = "//www.blogger.com/feeds/7833828309523986982/posts/default?start-index=0001&max-results=10&alt=json";
                var request = $.ajax({ url: BlogFeeds, dataType: 'jsonp' });

                return (request.then(handleSuccess));
            }
            function handleSuccess(response) {
                return (response.feed);
            }
        });

    </script>

</head>
<body>
    <div ng-app="myApp">
        <div ng-controller="picCtrl">
            {{message}}
            <span ng-repeat="entry in entries">
                <span >
                    <img ng-src="{{entry.media$thumbnail.url}}" />
                    {{entry.title.$t}}
                </span>
            </span>


        </div>
    </div>

</body>
</html>

loadData() loads data which is loaded using Angular services. Now when I assign the data to $scope.entries variable, it is not binding automatically.

am I missing something here ?

SenthilKumarM
  • 119
  • 1
  • 8
  • 1
    Possibly [Using jQuery's $.ajax within an angularJS controller](http://stackoverflow.com/questions/14716822/using-jquerys-ajax-within-an-angularjs-controller) – Jonathan Lonowski Jun 25 '14 at 20:18
  • use `$http` instead of `$.ajax`, it's already injected into your service: https://docs.angularjs.org/api/ng/service/$http – Jonathan Wilson Jun 25 '14 at 20:19
  • @Jonathan : I didnt use jQuery AJAX inside Controller, I used only it in service. So It doesnt make any difference to the data. – SenthilKumarM Jun 25 '14 at 20:20
  • it's in your service. The point is, don't use jQuery. See http://stackoverflow.com/questions/14994391/how-do-i-think-in-angularjs-if-i-have-a-jquery-background?rq=1 – Jonathan Wilson Jun 25 '14 at 20:20
  • 1
    @SenthilKumarM The controller still uses jQuery Ajax, just indirectly through the service. So, the point of the other post likely still applies. – Jonathan Lonowski Jun 25 '14 at 20:22
  • 3
    If you use the jQuery $.ajax then you will need to run `$scope.apply()` to get the data to propogate. As @JonathanWilson says, better to use angular's `$http` which will start a digest automatically – Simon H Jun 25 '14 at 20:22
  • I tried using $http, but I couldn't get the above JSON URL using $http, whereas I could get using jQuery AJAX. – SenthilKumarM Jun 25 '14 at 20:23
  • Then you need to learn $http on its own. Go to jsfiddle.net, make a testing application, and play with $http. – Jonathan Wilson Jun 25 '14 at 20:24
  • @Jonathan : $http throws me Cross Domain Resource sharing Error, while jQuery gets the JSON without any error.Please search "CORS" for more details. – SenthilKumarM Jun 25 '14 at 20:26
  • @SimonH : Is it possible to pass $scope as argument to a service ? – SenthilKumarM Jun 25 '14 at 20:32
  • No, you should load data in the service, and inject your service into your controller and then equate a scope variable with a jsonNews – Simon H Jun 25 '14 at 20:38
  • If you need to query cross-domain then you need to use [`$http.jsonp`](https://docs.angularjs.org/api/ng/service/$http#jsonp) or if you control the server allow access to the resource. – Terry Jun 25 '14 at 20:56
  • @Terry : I dont have any control to modify the server resources. I tried to implement the same using jsonp ( in angularJS), but still I am getting CORS error. while jQuery doesn't throws me any error. – SenthilKumarM Jun 26 '14 at 19:54

1 Answers1

3

Angular use two way binding but the case you mentioned in this case the $scope.entires array looses its scope in controller when you try to push items into it.

The better approach is to do this thing using $http service and all the things should do into myservice service. In this way code is more usable, readable and loosely coupled.

I have done in this way. May be it helps you. If you find any other approach please post it.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Http Jsonp Sample</title>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular-resource.min.js"></script>
    <script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
    <script>
        var myApp = angular.module("myApp", []);

        myApp.service('myservice', ['$http', '$q', function ($http, $q) {
            var entries = [];

            function getData(){
                var arr1 = [];
                var BlogFeeds = "//www.blogger.com/feeds/7833828309523986982/posts/default?start-index=0001&max-results=10&alt=json&callback=JSON_CALLBACK";

                $http.jsonp(BlogFeeds)
                .success(function(data){
                    angular.forEach(data.feed.entry, function(entryX){
                        arr1.push(entryX);
                    });
                    angular.copy(arr1, entries);
                })
                .error(function (data) {
                    $scope.data = "Request failed";
                });
            }

            return {
                getData: getData,
                entries: entries
            };

        }]);


        myApp.controller('picCtrl', function ($scope, myservice) {

            $scope.message = "Welcome";
            $scope.entries = myservice.entries;

            myservice.getData();

        });

    </script>

</head>
<body>
    <div ng-app="myApp">
        <div ng-controller="picCtrl">
            {{message}}
            <span ng-repeat="entry in entries">
                <span >
                    <img ng-src="{{entry.media$thumbnail.url}}" />
                    {{entry.title.$t}}
                </span>
            </span>
        </div>
    </div>
</body>
</html>
Artjom B.
  • 61,146
  • 24
  • 125
  • 222