angularjs

Angular form $invalid and $routeUpdate


I am implementing an advanced search in an application I'm working on. In this search I want the back and next buttons from the browser to work with the search.

To achieve this I added this to my $routeProvider:

.when('/search', {
    templateUrl: 'Scripts/App/Views/Search.html',
    controller: 'SearchController',
    reloadOnSearch: false
})

In my SearchController I have a search function on the $scope that just adds some query string parameters to my URL:

$scope.advancedSearch = function(){
    $location.search("page", $scope.currentPage);
    $location.search("groupingField", $scope.groupingField);
    $location.search("topgroup", angular.toJson($scope.filter));
}

I listen to $routeUpdate, get the query string parameters and execute the search with these parameters.

$scope.$on('$routeUpdate', function () {
    var qs = $location.search();
    var topGroup = qs["topgroup"];
    $scope.filter = angular.fromJson(topGroup);
    $scope.groupingField = qs["groupingField"];
    $scope.currentPage = qs["page"];
    performSearch();
});

In my real search method I check the form for errors. If there are any I show a message else I perform the search (do an API call).

var performSearch = function () {
    if ($scope.searchForm.$invalid) {
        $scope.message = "Please fix the errors before you search.";
    } else {
        //get search results from database and put them on $scope.
    }
}

With this code I can search and get the correct results. If I do a new search it also get's the correct results and I can use the back and next buttons from the browser.

When I do a search and my form is invalid the message shows, but when I go back after an invalid search the $invalid of the form updates after my "performSearch" method is called. This causes "Please fix the errors before you search." message to display even if the form is $valid.

If I click on the next button after this I get even more trouble since the form is $valid now but with the querystring parameters filled in it should be $invalid. Again this only updates after the performSearch has been called. which is to late.

It might be hard to understand my problem, if something is unclear ask away!


Solution

  • Found the answer! On the $routeupdate I waited for a digest cycle to finish and update the form properties. This can be done with a $timeout without a time.

    $scope.$on('$routeUpdate', function () {
        var qs = $location.search();
        var topGroup = qs["topgroup"];
        $scope.filter = angular.fromJson(topGroup);
        $scope.groupingField = qs["groupingField"];
        $scope.currentPage = qs["page"];
        $timeout(function () {
            performSearch();
        });
    });