0

Screencast: http://screencast-o-matic.com/watch/cDjX00isoo
All Javascript: http://fontget.com/js/all.js (at the bottom)
Demo of the issue: http://www.fontget.com

So I have this issue that I have been dealing with for a bit and can't seem to be able to figure it out. I am trying to give users the option of sorting the results from the database by clicking on a radio button with the specific filter.

When I click on the radio button I can see in the console that the correct url is grabbed using AJAX but the list is not getting updated in the view.

The page works when it is loaded for the first time (no sort filters).

The controller:

FontGet.controller('mainController', ['$scope', 'FontService', '$location', '$rootScope', '$routeParams', function($scope, FontService, $location, $rootScope, $routeParams) {
    $rootScope.hideFatMenu = false;
    $scope.navCollapsed = true;
    $scope.isSettingsCollapsed = true;
    $rootScope.header = "Welcome to FontGet.com!";
    $scope.sortBy = 'new';

    $scope.fonts = {
        total: 0,
        per_page: 10,
        current_page: ((typeof($routeParams.page) !== 'undefined') ? $routeParams.page : 1),
        loading: true
    };

    $scope.setPage = function() {
        FontService.call('fonts', { page: $scope.fonts.current_page, sort: $scope.sortBy }).then( function(data) {
            $scope.fonts = data.data;
            $scope.fonts.loading = false;

            document.body.scrollTop = document.documentElement.scrollTop = 0;
        });
    };


    $scope.$watch("sortBy", function(value) {
        $scope.setPage();
    });

    $scope.$watch("searchQuery", function(value) {
        if (value) {
            $location.path("/search/" + value);
        }
    });


    $scope.categories = FontService.categories();
    $scope.setPage();
}]);

The View:

<div class="fontdd" ng-repeat="font in fonts.data" >
    <!-- Stuff goes here. This is populated correctly when page initially loads -->
</div>

The sort buttons:

<ul class="radiobtns">
    <li>
        <div class="radio-btn">
            <input type="radio" value="value-1" id="rc1" name="rc1" ng-model="sorts" ng-change="sortBy = 'popular'">
            <label for="rc1" >Popularity</label>
        </div>
    </li>
    <li>
        <div class="radio-btn">
            <input type="radio" value="value-2" id="rc2" name="rc1" ng-model="sorts" ng-change="sortBy = 'trending'">
            <label for="rc2">Trending</label>
        </div>
    </li>
    <li>
        <div class="radio-btn">
            <input type="radio" value="value-4" id="rc4" name="rc1" checked="checked" ng-model="sorts" ng-change="sortBy = 'new'">
            <label for="rc4">Newest</label>
        </div>
    </li>
    <li>
        <div class="radio-btn">
            <input type="radio" value="value-3" id="rc3" name="rc1" ng-model="sorts" ng-change="sortBy = 'alphabetical'">
            <label for="rc3">Alphabetical</label>
        </div>
    </li>
</ul>

You will notice that the ng-model for the radio buttons is not set to sortBy. The reason for this is that if I set it to sortBy the AJAX call is made 4 times (no clue why thi is happening).

7
  • Quick answer to part of your question, anytime you use a scope.$watch, it'll get fired more often than you'd expect. To filter out just the watch events that you really want, add something like this in the watch function: if (newVal == null || newVal===oldVal) return;
    – Dr. Cool
    Commented Aug 11, 2016 at 22:59
  • @Dr.Cool data.data contains the correct data. setPage works just fine on the initial page load. The view doesn't change any time the data is changed by clicking the radio button. Commented Aug 11, 2016 at 23:10
  • @MeisamMulla, would be better if you could provide a demo that reproduces the issue.. by the way, why don't you create an array of objects to display these radio buttons (using ngRepeat) and simplify the things? Commented Aug 11, 2016 at 23:19
  • Yeah, a plunker would help and in the process of creating it you might discover what's wrong just by having to port it (and trim it down) into plunker.
    – Dr. Cool
    Commented Aug 11, 2016 at 23:21
  • @Dr.Cool Here is a screencast of it screencast-o-matic.com/watch/cDjX00isoo I'm going to publish the changes I have made so that you guys can see it Commented Aug 11, 2016 at 23:25

1 Answer 1

0

You're using a $scope.$watch function to watch for changes in the sortBy scope variable. You should try removing the watch and change your sort buttons' ng-change event to this:

    <div class="radio-btn">
        <input type="radio" value="value-1" id="rc1" name="rc1" ng-model="sorts" ng-change="Sort('popular')">
        <label for="rc1" >Popularity</label>
    </div>

In your controller, create a Sort() function:

$scope.Sort = function(sortBy) {
   $scope.sortBy = sortBy;
   $scope.setPage();
}

You don't really need to use $watch when you can just call a function and pass in the appropriate information.

3
  • It's still doing the same thing. The content is loaded correctly from what I can see in the console and $scope.fonts is updated as well but the view doesn't update. Commented Aug 11, 2016 at 23:13
  • @Dr.Cool, well, I agree that the use of ngChange is better than the use of $watch, however it doesn't change absolutely nothing in this case. Commented Aug 11, 2016 at 23:18
  • @developer033 The full javascript is at fontget.com/js/all.js (at the bottom) and the site is at fontget.com Commented Aug 11, 2016 at 23:29

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.