0

AngularJS ng-repeat not changing when array changes

I have a controller:

  <section data-ng-controller="FilmController">
    <article data-ng-view></article>
  </section>

This is its controller:

.controller('FilmController',
      [
        '$scope',
        'dataService',
        '$routeParams',
        function ($scope, dataService, $routeParams) {
          var getFilms = function(searchterm, category, page){
            dataService.getFilms(searchterm, category, page).then(
              function(response){
                $scope.films = [];
                $scope.films = response.data;
                let pageLinks = [];
                for (let i = 0; i < response.data[10][0]; i += 10) {
                  pageLinks.push({
                    pageLink: "/wai/wai-assignment/#/films?searchterm=" + searchterm + "&category=" + category + "&page=" + i/10,
                    pageNum: i/10
                  })
                }
                $scope.pageLinks = pageLinks;
                console.log(pageLinks);
              },
              function(err){
                $scope.status = 'Unable to load data' + err;
              },
              function(notify){
                console.log(notify);
              }
            );
          }

          if ($routeParams && ($routeParams.searchterm || $routeParams.category)){
            getFilms($routeParams.searchterm, $routeParams.category, $routeParams.page);
          } else {
            getFilms('','',$routeParams.page);
          }
        }
      ]);

These are the routes:

app.config(
        [
            '$routeProvider',

            function ($routeProvider) {
                $routeProvider
                    .when('/films', {
                        templateUrl: 'js/partials/films.html',
                        controller: 'FilmController'
                    })
                    .otherwise({
                        redirectTo: '/'
                    });
            }
        ]
    );

Here is the template:

<section>
  <table>
    <tr data-ng-repeat="film in films">
      <td>{{film.title}}</td>
      <td>{{film.name}}</td>
      <td>{{film.description}}</td>
    </tr>
  </table>
  <a data-ng-repeat="pageLink in pageLinks" ng-href="{{pageLink.pageLink}}">
    {{pageLink.pageNum}}
  </a>
</section>

When i access films?searchterm=example&category=example&page=1

It shows films with the category and search criteria from a database. When i click a link to go to a different page, it just grabs data from an SQL statement with a different OFFSET, but the ng-repeat doesn't update with it.

I know why this happens, something to do with scopes, but i can't work out how to fix it. Can anyone help?

EDIT:

angular.module('filmDirectoryApp')
    .service('dataService',
        [
          '$q',
          '$http',
          function ($q, $http) {
            var urlBase = 'server/';
            var defer = $q.defer();
            this.getFilms = function (searchterm, category, page) {
              $http.get(urlBase + 'getfilms.php?searchterm=' + searchterm + '&category=' + category + '&page=' + page)
                .success(function (response) {
                  console.log(response);
                  defer.resolve({
                      data: response
                  });
                })
                .error(function (err) {
                    defer.reject(err);
                });
                return defer.promise;
            }
          }
        ]
      );
7
  • @dota2pro ng-repeat='film in films' is the ng-repeat in question and it is version 1.5.6 Commented May 9, 2019 at 16:13
  • @dota2pro It is saying that it is changed but it isn't changing. I think the database request isn't working correctly. I'll see if i can get that fixed. Commented May 9, 2019 at 16:25
  • @dota2pro No that section is just to load the page links. It's not related i don't think. Commented May 9, 2019 at 16:32
  • So if i console.log(response) in the dataService, it returns the correct data. If i return the data that has supposedly been sent to the controller from that dataService then it logs the wrong data. Commented May 9, 2019 at 16:45
  • Please check if you get correct $scope.films value thanks Commented May 9, 2019 at 16:59

1 Answer 1

0

The code uses a deferred anti-pattern that is written incorrectly. The $q.defer only resolves once. Subsequent calls to defer.resolve are ignored. This is the way promises work.

In addition the .success and .error methods are deprecated and have been removed from the AngularJS framework.

The solution is to avoid the deferred anti-pattern and use the .then and .catch methods.

angular.module('filmDirectoryApp')
.service('dataService',
    [
      '$http',
      function ($http) {
        var urlBase = 'server/';
        this.getFilms = function (searchterm, category, page) {
          var params = {
              "searchterm": searchterm,
              "category"  : category,
              "page"      : page
          };
          var config = { "params": params };    
          return $http.get(urlBase + 'getfilms.php', config)
            .then(function (response) {
              var data = response.data;
              console.log(data);
              return data;
            })
            .catch(function (err) {
              console.log(err)
              throw err;
            });
        }
      }
    ]
);

The $http service deprecated custom callback methods - .success() and .error() - have been removed. You can use the standard .then()/.catch() promise methods instead, but note that the method signatures and return values are different.

The .then method returns a new promise which is resolved or rejected via the return value of the successCallback, errorCallback (unless that value is a promise, in which case it is resolved with the value which is resolved in that promise using promise chaining).

For more information, see

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks alot for this. The code you showed is identical to my previous code. How would i write a .then.catch variant of it?

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.